制作 Haskell 个 Monad
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
和 returns 一个 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
有种类 * -> *
。此外,绑定运算符将计算 f x
,然后使用 y+1
.
更改该实例的 myState
话虽这么说,现在您还需要使 EmptyMonad
成为 Applicative
和 Functor
的实例。
我正在尝试在 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
和 returns 一个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
有种类 * -> *
。此外,绑定运算符将计算 f x
,然后使用 y+1
.
myState
话虽这么说,现在您还需要使 EmptyMonad
成为 Applicative
和 Functor
的实例。