I create my own data type, and try to implement functor method as follow:
data Hieu a = Hieu [a] deriving (Show, Read, Eq)
instance Functor Hieu where
fmap f (Hieu [x]) = Hieu (f [x])
It's very simple piece of code but it failed. Can you explain why?
Thanks for all your responses. Now I understand that I apply functor only for one case. I tried to rewrite as follow, without using 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 []
Thanks for all your responses. Now I understand that I apply functor only for one case. I tried to rewrite as follow, without using 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 []
In the expression f [x] you're applying f to a list, but that's not allowed since the type signature of fmap is (a -> b) -> Hieu a -> Hieu b. You're not allowed to restrict f to [a] -> [b].
Perhaps you meant to write
instance Functor Hieu where
fmap f (Hieu [x]) = Hieu [f x]
This would compile, but it would only work if the list has exactly one element. The normal way of making Hieu a functor would be to use map to apply the function to all of the elements like so:
instance Functor Hieu where
fmap f (Hieu xs) = Hieu (map f xs)
You're only handling a single case, a one-element list, and handling it incorrectly. Type-level [a] (the type of lists of any length of as) is very different from value-level [x] (a list containing exactly one element, called x)!
The correct instance would involve using the function in a more involved way.
fmap :: (a -> b) -> Hieu a -> Hieu b
fmap f (Hieu xs) = Hieu (`...`)
At the ..., we have f :: a -> b and xs :: [a], and we want something :: [b]. There's a natural way to get that -- map the function over the list.
So a correct instance would look like:
instance Functor Hieu where
fmap f (Hieu xs) = Hieu (map f xs)
Any other instance -- for example, one that only handles one-element lists -- wouldn't obey the Functor laws, since we want fmap id h to always be the same thing as h.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With