Haskell 是否强制执行 monad 法则?
Are monad laws enforced in Haskell?
来自 Haskell wiki:
Monads can be viewed as a standard programming interface to various
data or control structures, which is captured by the Monad class. All
common monads are members of it:
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
In addition to implementing the class functions, all instances of
Monad should obey the following equations, or Monad Laws:
return a >>= k = k a
m >>= return = m
m >>= (\x -> k x >>= h) = (m >>= k) >>= h
问题:底层的三个 monad 法则实际上是由语言以任何方式强制执行的吗?或者它们是 you 必须执行的额外公理,以便 "Monad" 的语言结构与 "Monad" 的数学概念相匹配?
不,语言不强制执行 monad 法则。但是,如果您不遵守它们,您的代码在某些情况下可能不一定会像您期望的那样运行。这肯定会让您的代码的用户感到困惑。
你 负责强制 Monad
实例遵守 monad 法则。这是一个 不 .
的简单示例
即使它的类型与Monad
方法兼容,计算绑定运算符被使用的次数也不是Monad,因为它违反了法律m >>= return = m
{-# Language DeriveFunctor #-}
import Control.Monad
data Count a = Count Int a
deriving (Functor, Show)
instance Applicative Count where
pure = return
(<*>) = ap
instance Monad Count where
return = Count 0
(Count c0 a) >>= k =
case k a of
Count c1 b -> Count (c0 + c1 + 1) b
来自 Haskell wiki:
Monads can be viewed as a standard programming interface to various data or control structures, which is captured by the Monad class. All common monads are members of it:
class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a
In addition to implementing the class functions, all instances of Monad should obey the following equations, or Monad Laws:
return a >>= k = k a m >>= return = m m >>= (\x -> k x >>= h) = (m >>= k) >>= h
问题:底层的三个 monad 法则实际上是由语言以任何方式强制执行的吗?或者它们是 you 必须执行的额外公理,以便 "Monad" 的语言结构与 "Monad" 的数学概念相匹配?
不,语言不强制执行 monad 法则。但是,如果您不遵守它们,您的代码在某些情况下可能不一定会像您期望的那样运行。这肯定会让您的代码的用户感到困惑。
你 负责强制 Monad
实例遵守 monad 法则。这是一个 不 .
即使它的类型与Monad
方法兼容,计算绑定运算符被使用的次数也不是Monad,因为它违反了法律m >>= return = m
{-# Language DeriveFunctor #-}
import Control.Monad
data Count a = Count Int a
deriving (Functor, Show)
instance Applicative Count where
pure = return
(<*>) = ap
instance Monad Count where
return = Count 0
(Count c0 a) >>= k =
case k a of
Count c1 b -> Count (c0 + c1 + 1) b