[英]Making Haskell Monads
我正在尝试在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.
这里有两个主要问题:
* -> *
。 因此,例如[]
而不是 [a]
; 和 >>=
期望EmptyMonad a
和函数a -> EmptyMonad b
并返回EmptyMonad b
元素。 因此,我们可以使用以下解决方案解决问题:
instance Monad EmptyMonad where -- no a after EmptyMonad
return x = EmptyMonad x 0
(EmptyMonad x y) >>= f = fx {myState = y+1}
where fx = f x
所以在这里我们指定instance Monad EmptyMonad
因为EmptyMonad
具有* -> *
。 此外,bind运算符将计算fx
,然后使用y+1
更改该实例的myState
。
话虽如此,如今您还需要使EmptyMonad
成为Applicative
和Functor
的实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.