christian wuensche
christian wuensche

Reputation: 1043

Haskell example where pure and return not interchangeable

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

Answers (1)

Robin Zigmond
Robin Zigmond

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

Related Questions