This is a book exercise (as usual for me) and I really don’t understand the type:
data List a = Nil | Cons a (List a)
List a
in Cons a (List a)
looks like a data constructor but I don’t know how to use it. Nor do I know how to use the types methods.
The exercise gives the type and asks that you create instances for Functor
, Applicative
& Monad
.
Here is the answer I found on Github:
data List a = Nil | Cons a (List a)
deriving (Show, Eq)
append :: List a -> List a -> List a
append Nil ys = ys
append (Cons x xs) ys = Cons x $ xs `append` ys
instance Functor List where
fmap _ Nil = Nil
fmap f (Cons a as) = Cons (f a) (fmap f as)
instance Applicative List where
pure a = Cons a Nil
Nil <*> _ = Nil
_ <*> Nil = Nil
(Cons f fs) <*> as = fmap f as `append` (fs <*> as)
instance Monad List where
return = pure
Nil >>= _ = Nil
(Cons a as) >>= f = f a `append` (as >>= f)
My attempts to make use of it
ghci> (Cons 5 [2,3]) >>= (+1)
<interactive>:7:9: error:
• Couldn't match expected type: List (List b)
with actual type: [a0]
• In the second argument of ‘Cons’, namely ‘[2, 3]’
In the first argument of ‘(>>=)’, namely ‘(Cons 5 [2, 3])’
In the expression: (Cons 5 [2, 3]) >>= (+ 1)
• Relevant bindings include
it :: List b (bound at <interactive>:7:1)
ghci> fmap (+1) (Cons 5 [3,4])
<interactive>:8:19: error:
• Couldn't match expected type: List b
with actual type: [a0]
• In the second argument of ‘Cons’, namely ‘[3, 4]’
In the second argument of ‘fmap’, namely ‘(Cons 5 [3, 4])’
In the expression: fmap (+ 1) (Cons 5 [3, 4])
ghci> fmap (+1) (Cons 5 List [3,4])
<interactive>:9:19: error:
Data constructor not in scope: List :: List a1
> (Cons 5 [2,3]) >>= (+1)
-- Error
> (Cons 5 (List [2,3])) >>= (+1)
```Error
But neither are conrrect usage.
I'm thinking of `List a` as a type that is only visible withoun `Cons`. Is that right/
What would be an example of using this type from GHCi?