Пример 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
это традиционный пример.