(更新:どうやら私の元の答えはOPにはあまり役に立ちませんでした...付録については以下の2番目のHRを参照してください。)
このような状況で本当にやりたいのは、起動してさまざまな式の種類を見つけるためにghci
使用することです。:t
例えば
:t foldr map
-- answer: foldr map :: [b] -> [b -> b] -> [b]
最初に名前を定義する必要がある場合は、次を使用しますlet
(Haskellソースファイルでは必要ありません)。
let mys = undefined :: a -> a
:t map mys
-- answer: [a] -> [a]
undefined
明示的な型シグニチャーでの使用に注意してください。さまざまな形式の式のタイプを見つけるのに完全に問題はなく、計画の初期段階でプレースホルダーとして実際のコードで役立つ場合もあります。
は;Num a =>
の型クラス制約です。a
詳細については 、「A Gentle Introduction to Haskell、Version98」または第6章「RealWorldHaskell 」の型クラスの使用などの型クラスとオーバーロードを参照してください。(基本的に、それはあなたが思うことをします。:-))
上記はあなたの答えを確認するのに役立つはずです(そして型クラスのリソースは良いです)。この種の問題を自分で解決する方法については、次のようになります。
型推論は、いわゆる「統合アルゴリズム」のアプリケーションです。多くのリソースの「統一」のためのグーグル。プログラミング言語の名前をクエリに追加すると、実装例が見つかる可能性があります。
手元の例へのアプローチ方法については...
a。map mys
:map
型の関数を受け取り、型a -> b
の関数を返します[a] -> [b]
。一般に、a
とは異なる場合b
がmys
ありますが、タイプa -> a
はであるため、返される関数はタイプになり[a] -> [a]
ます。
ここにいくつかの手による統一があります:
(a -> b) -> [a] -> [b]`
(a -> a)`
^-- at this point we unify a with b;
when propagated to the return type,
this produces [a] -> [a]
b。mys map
:mys
は、あるタイプのオブジェクトを受け取り、同じタイプのオブジェクトを返す関数です。特に、型の引数を渡すと、それ(a -> b) -> [a] -> [b]
が戻り値の型になります。
undefined
ちなみに、型シグネチャがa -> a
(型クラスの制約なしで)である「興味深い」(ではない)関数は1つだけです。つまり、id
です。フィリップ・ワドラーの論文「Theorems forfree!」を参照してください。(このページからダウンロードできます)詳細な説明があります。
c。:まず、の署名のsとsは、の署名のsとsとは何の関係もないことfoldr map
に注意してください。の名前をtoとtoに変更し、署名を使用して、これを以下でより簡単に明らかにするのが便利な場合があります。また、これはより簡単な記述方法であることに注意してください。a
b
foldr
map
map
a
c
b
d
map :: (c -> d) -> [c] -> [d]
(a -> b -> b)
(a -> (b -> b))
より多くの手による統一(説明は以下に続きます):
(a -> (b -> b))
(c -> d) -> [c] -> [d]
ここで何が起こるかというと、それfoldr
は型の関数引数を取るということ(a -> (b -> b))
です。map
その引数として渡すと、は、、 with 、そして再びwithでa
統合されます。これは、に等しいことを意味します。c -> d
b
[c]
[d]
c
d
の戻り値のfoldr
タイプはb -> [a] -> b
;です。前の段落で取得したより具体的なタイプを置き換えると、
[c] -> [c -> c] -> [c]
^-- c equals d, right?
は、 ;c
の変更された署名に由来します。map
オリジナルb
で、これは
[b] -> [b -> b] -> [b]
d。foldr map . mys
:これは実際(foldr map) . mys
にはそうではありませんfoldr (map . mys)
-関数適用(「見えない演算子」)は最強をバインドします!組み合わせるa。およびc。これを解決するために上から、読者への練習として残されています。;-)