特别是Monad。哈斯克尔

时间:2016-05-13 17:11:12

标签: haskell

我写了一个代表一些计算的monad。现在,我想定义计算应该是sequenced的方式。所以,我将定义>>=。但是,对流量的控制迫使我把注意力集中在a的混淆类型上。我的意思是:

m >>= f = 
     a <- m 
     case a of
        (ParticularParameterA) -> doSomething
          ..........

这是正确的解决方案吗?我的意思是:我没有函数式编程经验,所以我不确定是否可以。怎么做得更好?

2 个答案:

答案 0 :(得分:2)

虽然case语句和语法错误,但这个定义确实显然是荒谬的,因为来自do-block的绑定被转换为>>=的使用。因此,您现有的代码已经定义了m >>= f = m >>= \a -> ...,这是一个无限循环和空间泄漏。

答案 1 :(得分:1)

您的情况可能属于简单模式,即monad格式:

newtype MyMonad a = MyMonad { run :: State -> (a, State) }

其中State是您自己设计的数据类型。关键是你可能有一个功能:

run :: MyMonad a -> State -> (a, State)

您可能需要在实现(&gt;&gt; =)时使用此功能:

m >>= f = MyMonad(\state -> let (x, newState) = run m state in
                              case x of 
                                (ParticularParameterA) -> doSomething
                                 ..........

现在如果f::a -> MyMonad b您的\state -> ...函数必须返回(b, State),那么您可能希望在代码中的某处使用run (f x) newState

如果你的monadic类型是以下形式:

newtype MyMonad a = MyMonad { run :: State -> Maybe (a, State) }
newtype MyMonad a = MyMonad { run :: State -> Either String  (a, State) }

然后你仍然使用run函数,例如

m >>= f = MyMonad (\state -> case run m state of
                               Just (x, newState) -> run (f x) newState
                               Nothing               -> Nothing)