【发布时间】:2018-03-15 00:15:22
【问题描述】:
我正在尝试在 Haskell 中创建一个非常简单的 monad。 monad 没有什么特别的,只是持有一个计数器作为状态。
module EmptyMonad
( EmptyMonad
) where
import Control.Monad
data EmptyMonad a = EmptyMonad
{ myValue :: a
, myState :: Int
} deriving (Show)
instance (Eq a) => Eq (EmptyMonad a) where
EmptyMonad x1 y1 == EmptyMonad x2 y2 = x1 == x2 && y1 == y2
instance Monad (EmptyMonad a) where
return x = EmptyMonad x 0
(EmptyMonad x y) >>= f = EmptyMonad x (y + 1)
在 Monads 上花了几个小时后,我无法理解编译器的错误:
EmptyMonad.hs:16:10: error:
• Expecting one fewer argument to ‘Monad EmptyMonad’
Expected kind ‘k0 -> Constraint’,
but ‘Monad EmptyMonad’ has kind ‘Constraint’
• In the instance declaration for ‘Monad EmptyMonad a’
Failed, modules loaded: none.
【问题讨论】:
-
你应该写
instance Monad EmptyMonad where(没有a)。 -
此外,它应该是
(EmptyMonad x y) >>= f = EmptyMonad (f x) (y + 1)。 (与f),否则类型不匹配。 -
除了理解和使用 Haskell 语法的问题之外,您还会遇到语义问题。在 monad 中计数绑定是不行的;它违反了“
return是一个身份”定律,即return x >>= f = f x,因为等式右侧的绑定较少。 (不过,这似乎是每个人对新 monad 的第一个想法,包括我的!) -
参见this question,它也询问了“counter monad”。