Still not a hundred percent shure how to make instances of the more complex types. Have this:
data CouldBe a = Is a | Lost deriving (Show, Ord)
Made an instance of Functor
, using Maybe
as an example:
instance Functor CouldBe where
fmap f (Is x) = Is (f x)
fmap f Lost = Lost
For doing something like this:
tupleCouldBe :: CouldBe a -> CouldBe b -> CouldBe (a,b)
tupleCouldBe x y = (,) <$> x <*> y
CouldBe
needs to be an instance of Applicative
, but how would you go about that? Sure I can look it up and copy it, but I want to learn the process behind it and finally end up with the instance
declaration of CouldBe.
You just write it out, following the types:
instance Applicative CouldBe where
{-
Minimal complete definition:
pure, ((<*>) | liftA2)
pure :: a -> f a
pure :: a -> CouldBe a
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
liftA2 :: (a -> b -> c) -> CouldBe a -> CouldBe b -> CouldBe c
-}
pure a = fa
where
fa = ....
liftA2 abc fa fb = fc
where
fc = ....
According to
data CouldBe a = Is a | Lost
our toolset is
Is :: a -> CouldBe a
Lost :: CouldBe a
but we can also use pattern matching, e.g.
couldBe is lost (Is a) = is a
couldBe is lost (Lost) = lost
couldBe :: ? -> ? -> CouldBe a -> b
couldBe :: ? -> b -> CouldBe a -> b
couldBe :: (a -> b) -> b -> CouldBe a -> b
So,
-- pure :: a -> f a
pure :: a -> CouldBe a
matches up with
Is :: a -> CouldBe a
so we define
pure a = Is a
Then, for liftA2
, we follow the data cases:
-- liftA2 :: (a -> b -> c) -> f a -> f b -> f c
-- liftA2 :: (a -> b -> c) -> CouldBe a -> CouldBe b -> CouldBe c
liftA2 abc Lost _ = ...
liftA2 abc _ Lost = ...
liftA2 abc (Is a) (Is b) = fc
where
c = abc a b
fc = .... -- create an `f c` from `c`:
-- do we have a `c -> CouldBe c` ?
-- do we have an `a -> CouldBe a` ? (it's the same type)
But in the first two cases we don't have an a
or a b
; so we have to come up with a CouldBe c
out of nothing. We do have this tool in our toolset as well.
Having completed all the missing pieces, we can substitute the expressions directly into the definitions, eliminating all the unneeded interim values / variables.