Reputation: 627
I am new to Haskell. I've made a type Maybe3.
data Maybe3 a= Just3 a| Unknown3 | Missing3 deriving (Show, Eq, Ord)
eq3 :: Eq a => Maybe3 a-> Maybe3 a-> Bool3
eq3 Unknown3 _ = Unk3
eq3 Missing3 _ = False3
eq3 _ Missing3 = False3
eq3 _ Unknown3 = Unk3
eq3 (Just3 a) (Just3 b)=if a==b then True3 else False3
How to make Maybe3 an applicative functor? And how to make it a Monad?
Upvotes: 3
Views: 554
Reputation: 32455
My understanding is that Missing3
and Unknown3
work a bit like Nothing
, except they give a little more feedback about why there's no answer, so might behave slightly differently to each other. Certainly I think Missing3
should behave like Nothing
.
Let's look at how these are defined for Maybe
:
Here's the Functor instance for Maybe
:
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
I think it's clear how to deal with Missing3
and Unknown3
here.
instance Monad Maybe where
(Just x) >>= k = k x
Nothing >>= _ = Nothing
(Just _) >> k = k
Nothing >> _ = Nothing
return = Just
fail _ = Nothing
You can't help but do the same here with >>=
for Missing3
and Unknown3
, since you don't have a value to bind with. The only question is do you fail with Unknown3
or Missing3
?
Here's where there's a little more digging:
instance Applicative Maybe where
pure = return
(<*>) = ap
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap = liftM2 id
liftM2 :: (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
Now that translates to
mf <*> mx = do
f <- mf
x <- mx
return (f x)
Which you can use all the time to turn a Monad into an Applicative.
In fact, whenever you find yourself writing
this thing = do
something <- some monadic thing
more <- some other thing
yetmore <- another thing too
return (combine something more yetmore)
you should rewrite it using applicative notation:
this thing = combine <$> some monadic thing
<*> some other thing
<*> another thing too
Upvotes: 5