2

独自のデータ型を作成し、次のように functor メソッドを実装しようとしています。

data Hieu a = Hieu [a] deriving (Show, Read, Eq)

instance Functor Hieu where
        fmap f (Hieu [x]) = Hieu (f [x])

これは非常に単純なコードですが、失敗しました。理由を説明できますか?


ご回答ありがとうございます。これで、functor を 1 つのケースにのみ適用することがわかりました。map を使用せずに、次のように書き換えてみました

data Hieu a = Hieu [a] deriving (Show, Read, Eq)

consHieu :: a -> (Hieu a) -> (Hieu a)
consHieu x (Hieu xs) = Hieu (x:xs)

instance Functor Hieu where
    fmap f (Hieu (x:xs)) = consHieu (f x) (fmap f (Hieu xs))
    fmap f (Hieu []) = Hieu []

ご回答ありがとうございます。これで、functor を 1 つのケースにのみ適用することがわかりました。map を使用せずに、次のように書き換えてみました

データ Hieu a = Hieu [a] の導出 (Show、Read、Eq)

consHieu :: a -> (Hieu a) -> (Hieu a)

consHieu x (Hieu xs) = Hieu (x:xs)

インスタンス Functor Hieu where

    fmap f (Hieu (x:xs)) = consHieu (f x) (fmap f (Hieu xs))
    fmap f (Hieu []) = Hieu []
4

2 に答える 2

6

リストにf [x]適用している式では、の型シグネチャがisであるため、それは許可されていません。に制限することはできません。ffmap(a -> b) -> Hieu a -> Hieu bf[a] -> [b]

たぶん、あなたは書くつもりだった

instance Functor Hieu where
   fmap f (Hieu [x]) = Hieu [f x]

これはコンパイルされますが、リストに要素が 1 つだけある場合にのみ機能します。Hieuファンクターを作成する通常の方法はmap、関数を次のようにすべての要素に適用することです。

instance Functor Hieu where
   fmap f (Hieu xs) = Hieu (map f xs)
于 2012-11-18T03:31:20.287 に答える
4

単一のケース、1 つの要素のリストのみを処理し、それを誤って処理しています。型レベル[a](任意の長さのリストの型) は、値レベル(正確に 1 つの要素を含む、 と呼ばれるリストa) とは大きく異なります![x]x

正しい例では、より複雑な方法で関数を使用する必要があります。

fmap :: (a -> b) -> Hieu a -> Hieu b
fmap f (Hieu xs) = Hieu (`...`)

にはと...f :: a -> bありxs :: [a]、何かが欲しい:: [b]。それを取得する自然な方法があります-リストに関数をマップします。

したがって、正しいインスタンスは次のようになります。

instance Functor Hieu where
    fmap f (Hieu xs) = Hieu (map f xs)

他のインスタンス (たとえば、1 つの要素のリストのみを処理するインスタンス) は Functor の法則には従わないでしょfmap id hh

于 2012-11-18T03:32:23.487 に答える