代码之家  ›  专栏  ›  技术社区  ›  user1

制作哈斯克尔单子

  •  0
  • user1  · 技术社区  · 7 年前

    我试图用Haskell创建一个非常简单的单子。

    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)
    

    在单子上花了几个小时后,我无法理解编译器的错误:

    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.
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   user1    7 年前

    这里有两个主要问题:

    • 一种 友善的 * -> * . 比如说 [] , [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 *->* f x 然后改变 myState 在这种情况下 y+1

    清空菜单 的实例 Applicative Functor