简体   繁体   English

制作Haskell Monads

[英]Making Haskell Monads

I'm trying to create a very simple monad in Haskell. 我正在尝试在Haskell中创建一个非常简单的monad。 The monad does nothing special but holding a counter as state. 该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)

After spending few hours on Monads, I cannot get my head around the error from the compiler: 在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.

There are two main problems here: 这里有两个主要问题:

  • the instance declaration does expect a type of kind * -> * . 实例声明确实希望一种类型* -> * So for instance [] , not [a] ; 因此,例如[] 而不是 [a] and
  • the bind operator >>= expect an EmptyMonad a , and a function a -> EmptyMonad b and returns an EmptyMonad b element. 绑定运算符>>=期望EmptyMonad a和函数a -> EmptyMonad b并返回EmptyMonad b元素。

So we can fix the problems with the following solution: 因此,我们可以使用以下解决方案解决问题:

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

So here we specify instance Monad EmptyMonad since EmptyMonad has kind * -> * . 所以在这里我们指定instance Monad EmptyMonad因为EmptyMonad具有* -> * Furthermore the bind operator will calculate fx and then alter the myState of that instance with y+1 . 此外,bind运算符将计算fx ,然后使用y+1更改该实例的myState

That being said, nowadays you need to make EmptyMonad an instance of Applicative and Functor as well. 话虽如此,如今您还需要使EmptyMonad成为ApplicativeFunctor的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM