Пример Haskell, где чистый и возврат не взаимозаменяемы - PullRequest
0 голосов
/ 18 февраля 2019

Функция Haskell pure совпадает с return?

Я просто могу сделать тип экземпляром Monad, если он уже является экземпляром Applicative, верно?Поэтому мне интересно, что Applicative pure всегда взаимозаменяем с Monad 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 Ответ

0 голосов
/ 18 февраля 2019

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

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

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

  • pure = return

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

(>>=)

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

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

...