Reputation: 1043
Is Haskell's pure
function the same as return
?
I just can make a type an instance of Monad if it is already an instance of Applicative, right? So I wonder that Applicative's pure
is everytime interchangeable with Monad's return
?
Is there an example where they are not the same?
data HelloType a = HelloType { getValue :: a } deriving (Show, Eq)
instance Functor HelloType where
fmap f (HelloType y) = HelloType (f y)
instance Applicative HelloType where
(<*>) (HelloType f) (HelloType x) = HelloType (f x)
pure = HelloType
instance Monad HelloType where
(>>=) (HelloType x) f = f x
-- return = pure
return = HelloType
plus3 :: (Num a) => Maybe a -> HelloType (Maybe a)
plus3 (Just x) = HelloType (Just $ x + 3)
plus3 Nothing = HelloType Nothing
main= do
let withPure = pure (Just 3) >>= plus3 >>= plus3
withReturn = return (Just 3) >>= plus3 >>= plus3
print $ withPure == withReturn -- TRUE
Upvotes: 5
Views: 832
Reputation: 18249
Every type that is an instance of Monad must have its return
equal to pure
.
In particular, since Applicative
was made a superclass of Monad
, return
doesn't need to be defined because by default it is defined to be a synonym of pure
: see the definition:
Furthermore, the Monad and Applicative operations should relate as follows:
pure = return
Minimal complete definition
(>>=)
Notice that the minimal definition only requires >>=
, not return
, and the requirement that pure = return
(which, like all such "laws", cannot be enforced by the language but must hold for all "sane" implementations, otherwise the semantics will not be correct).
But there are types which are Applicative but not a Monad, and therefore have a pure
but no return
. ZipList
is the traditional example.
Upvotes: 9