Пример Haskell, где чистый и возврат не взаимозаменяемы

Хаскелла pure функционировать так же, как return?

Я просто могу сделать тип экземпляром Monad, если это уже экземпляр Applicative, верно? Так что мне интересно, что Applicative pure всегда взаимозаменяемы с монадой return? Есть ли пример, где они не совпадают?

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

1 ответ

Решение

Каждый тип, который является экземпляром Monad, должен иметь свой return равно pure,

В частности, так как Applicative был сделан суперкласс Monad, return не нужно определять, потому что по умолчанию он определен как синоним pure посмотреть определение:

Кроме того, операции Monad и Applicative должны быть связаны со следующим:

  • pure = return

Минимальное полное определение

(>>=)

Обратите внимание, что минимальное определение требует только >>= не return и требование, чтобы pure = return (который, как и все такие "законы", не может быть применен языком, но должен соблюдаться для всех "вменяемых" реализаций, в противном случае семантика не будет правильной).

Но есть типы, которые являются Аппликативными, но не Монадой, и поэтому имеют pure но нет return, ZipList это традиционный пример.

Другие вопросы по тегам