I made a new List of Maybe Monad instance and tried to prove the implementation does satisfy the Monad laws, am I doing it right or is the implementation incorrect? Any pointer is appreciated. Thanks!
newtype Test a = Test { getTest :: [Maybe a] }
deriving Functor
instance Applicative Test where
pure = return
(<*>) = liftM2 ($)
instance Monad Test where
return :: a -> Test a
return a = Test $ [Just a]
(>>=) :: Test a -> (a -> Test b) -> Test b
Test [Nothing] >>= f = Test [Nothing]
Test [Just x] >>= f = f x
{-
1. return x >>= f = f x
return x >>= f = [Just x] >>= f = f x
2. m >>= return = m
[Nothing] >>= return = [Nothing]
[Just x] >>= return = return x = [Just x]
3. (m >>= f) >>= g == m >>= (\x -> (f x >>= g))
m = [Nothing]
L.H.S. = ([Nothing] >>= f ) >>= g = Nothing >>= g = Nothing
R.H.S. = [Nothing] >>= (\x -> (f x >>= g)) = Nothing
m = [Just x]
L.H.S. = ([Just x] >>= f) >>= g = f x >>= g
R.H.S. = [Just x] >>= (\v -> (f v >>= g)) = (\v -> (f v >>= g)) x
= f x >>= g
-}
Test [] >>= f
orTest [Just x, Just y] >>= f
? – David Fletcher>>=
before. – chipure
directly,return
has a default definition ofreturn = pure
, sinceApplicative
is now a superclass ofMonad
. (Same amount of work, but fits with the modern Functor-Applicative-Monad hierarchy, rather than the old assumption that aMonad
instance for a type already exists when it comes time to write anApplicative
instance.) – chepner(>=>) :: (a -> m b) -> (b -> m c) -> a -> m c
/(<=<) = flip (>=>)
) rather than application (>>=
/=<<
), since then they’re phrased more symmetrically: 1. left identityreturn >=> x
=x
; 2. right identityx >=> return
=x
; and 3. associativity(x >=> y) >=> z
=x >=> (y >=> z)
. This also more clearly shows their relationship to theMonoid
,Alternative
, andCategory
laws. – Jon Purdy