Reputation: 57
The problem I'm stumbled at has to do with >>=
application to a sample type like that:
data ThreeArgs a = ThreeArgs a a a deriving (Show,Eq)
instance Functor ThreeArgs where
fmap f (ThreeArgs a b c) = ThreeArgs (f a) (f b) (f c)
instance Applicative ThreeArgs where
pure x = ThreeArgs x x x
(ThreeArgs a b c) <*> (ThreeArgs p s q) = ThreeArgs (a p) (b s) (c q)
I'd declare a Monad instance as follows:
instance Monad ThreeArgs where
return x = ThreeArgs x x x
(ThreeArgs a b c) >>= f = f ... -- a code I need to complete
Yes, it looks as if f
to be applied to all three ThreeArgs
contructor arguments. If I complete last line
(ThreeArgs a b c) >>= f = f a
then compiler doesn't have any complaints, whereas result is:
*module1> let x = do { x <- ThreeArgs 1 2 3; y <- ThreeArgs 4 6 7; return $ x + y }
*module1> x
ThreeArgs 5 5 5
it means that summation results into a context with same argument values, although correct output should be ThreeArgs 5 8 10
. Once I edit to
(ThreeArgs a b c) >>= f = (f a) (f b) (f c)
compiler alerts:
Couldn't match expected type `ThreeArgs b
-> ThreeArgs b -> ThreeArgs b -> ThreeArgs b'
with actual type `ThreeArgs b'
So, I see a serious mistake guides my comprehension, but it's still rather hard to me to understand monadic class and another such things in Haskell. Presumably, do I want to use recursion here or what else?
Upvotes: 3
Views: 256
Reputation: 48572
ThreeArgs
is isomorphic to ((->) Ordering)
. Witness:
to :: ThreeArgs a -> Ordering -> a
to (ThreeArgs x _ _) LT = x
to (ThreeArgs _ y _) EQ = y
to (ThreeArgs _ _ z) GT = z
from :: (Ordering -> a) -> ThreeArgs a
from f = ThreeArgs (f LT) (f EQ) (f GT)
Your Functor
and Applicative
instances match how the ones for ((->) r)
work, so we can just make it match how its Monad
one works too and we're done.
instance Monad ThreeArgs where
ThreeArgs x y z >>= f = ThreeArgs x' y' z' where
ThreeArgs x' _ _ = f x
ThreeArgs _ y' _ = f y
ThreeArgs _ _ z' = f z
By the way, the general term for data structures like ThreeArgs
is "representable functor", if you want to look up more about this.
Upvotes: 7