Functorのfmapのタイプは次のとおりです。
fmap :: Functor f => (a -> b) -> f a -> f b
最初に関数(a-> b)をfaのパラメーターに適用して、タイプbの結果を作成し、次にfを適用すると、結果はfbのようになります。
それはのタイプですがfmap
、そのタイプが何を意味するかについてのあなたの解釈は間違っています。
f a
には1つのパラメーターがあり、そのパラメーターのタイプは。であると想定しているようですa
。
考えてみてくださいxs :: [a]
:
- おそらく
xs = []
。
- おそらく
xs = [x1]
。
- おそらく
xs = [x1, x2]
。
- ..。
タイプ は、単一のタイプパラメーターを持つファンf a
クターです。ただし、上記の1番目と3番目のケースからわかるように、 typeの値は必ずしも形式をとる必要はありません。f
a
f a
F x
今考えてみましょうfmap f xs
:
- おそらく
fmap f xs = []
。
- おそらく
fmap f xs = [f x1]
。
- おそらく
fmap f xs = [f x1, f x2]
。
- ..。
必ずしも適用する必要はありませんf
(最初のケース)!または、複数回適用する場合があります(3番目の場合)。
私たちがしていることは、タイプのものをタイプのものに置き換えることa
ですb
。ただし、大きな構造はそのままにしておきます。新しい要素は追加されず、要素は削除されず、順序は変更されません。
それでは、ファンクターについて考えてみましょう(c ->)
。(ファンクターは1つの型パラメーターのみを受け取るため、への入力(->)
は固定されていることに注意してください。)
c -> a
も含まれていa
ますか?sがまったく含まれていない可能性がありますがa
、を与えると、どういうわけか薄い空気から魔法のようなものになる可能性がありますc
。しかし、からの結果にfmap
はタイプがあります。が表示されたときに、その中c -> b
からを提供するだけで済みます。b
c
だから私たちは言うことができますfmap f x = \y -> f (x y)
。
この場合、f
オンデマンドで適用しています---返される関数が適用されるたびに、f
同様に適用されます。