これにも問題があり、ラモンとミハイルの回答が有益であることがわかりました-ありがとう! 500 文字では短すぎるため、またコードの書式設定のために、これをコメントではなく回答に入れています。
私は何が共変であるかを理解するのに苦労していました.Functorのインスタンスにすることができる(a -> Int)
この反例を思いつきました(Ramonの証明を反証します)data K a = K (a -> Int)
data K a = K (a -> Int)
instance Functor K where
fmap g (K f) = K (const 0)
コンパイルできれば、それは正しいはずですよね? ;-) 他の順列を試すのに時間を費やしました。関数をフロップするだけで簡単になりました。
-- "o" for "output"
-- The fmapped (1st) type is a function output so we're OK.
data K0 o = K0 (Int -> o)
instance Functor K0 where
fmap :: (oa -> ob) -> (K0 oa) -> (K0 ob)
fmap g (K0 f) = K0 (g . f)
Int を型変数に変換すると、セクション 3.2 演習 1 パート 2 になりました。
-- The fmapped (2nd) type argument is an output
data K1 a b = K1 (a -> b)
instance Functor (K1 a) where
fmap :: (b1 -> b2) -> K1 a b1 -> K1 a b2
fmap g (K1 f) = K1 (g . f)
fmapped型を関数の引数にすることが鍵でした...ミハイルの答えが言ったように、今ではそれを理解しています;-)
-- The fmapped (2nd) type argument is an input
data K2 a b = K2 (b -> a)
instance Functor (K2 o) where
fmap :: (ia -> ib) -> (K2 o ia) -> (K2 o ib)
-- Can't get our hands on a value of type o
fmap g (K2 f) = K2 (const (undefined :: o))
-- Nor one of type ia
fmap g (K2 f) = K2 (const (f (undefined :: ia)))