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?
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.
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