(更新:どうやら私の元の答えは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に変更し、署名を使用して、これを以下でより簡単に明らかにするのが便利な場合があります。また、これはより簡単な記述方法であることに注意してください。abfoldrmapmapacbdmap :: (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 -> db[c][d]cd
の戻り値の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。これを解決するために上から、読者への練習として残されています。;-)