纯和返回不可互换的 Haskell 示例

标签 haskell monads applicative

是 Haskell 的 pure功能同return ?

如果一个类型已经是 Applicative 的一个实例,我就可以让一个类型成为 Monad 的一个实例,对吗?所以我想知道 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

最佳答案

Monad 实例的每个类型都必须有它的 return等于 pure .

特别是,由于 Applicative成为 Monad 的父类(super class), return不需要定义,因为默认情况下它被定义为 pure 的同义词: 见 the definition :

Furthermore, the Monad and Applicative operations should relate as follows:

  • pure = return


Minimal complete definition

(>>=)


请注意,最小定义只需要 >>= , 不是 return , 以及 pure = return 的要求(与所有此类“法律”一样,语言不能强制执行,但必须适用于所有“合理”实现,否则语义将不正确)。

但是有些类型是 Applicative 而不是 Monad,因此有 pure但没有 return . ZipList 是传统的例子。

关于纯和返回不可互换的 Haskell 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54750784/

相关文章:

haskell - xmonad - 使用鼠标按钮 6 和 7 切换工作区

haskell - 我可以使用状态 monad 模拟交互式程序吗?

haskell - monad 声明中带有 lambda 符号 "m >> n = m >>=\_ -> n "的等式是什么?

Haskell - 应用/Monad 实例

list - Haskell - 我自己的 zip3 函数

haskell - f# 相当于 Haskell 的 "interact"

haskell - 即使使用 bang 模式,ghci 内存也会增加

haskell - 将函数a→b用作 "monadic"函数a→m b

parsing - 在应用解析中苦苦挣扎

haskell - 为自定义 ZipList 实现 Applicative