2016-05-13 61 views
0

我写了一个代表一些计算的单子。现在,我想定义如何计算应该是sequenced。所以,我要定义>>=。但是,流量的控制迫使我把注意力集中在a的conrete类型上。我的意思是:特别是Monad。 Haskell

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

它是否正确的解决方案?我的意思是:我没有功能编程方面的经验,所以我不确定可以做或不做。如何做得更好?

+1

'm'应该已经有一个固定的类型,通过monad实例,所以不应该有切换需要也不可能。你的意思是你选择/切换monad类型的构造函数吗? – MicroVirus

+0

是的,确实如此。我编辑过。 – Gilgamesz

+0

你的编辑只是让代码变得荒谬,在do-block/list理解之外有一个'<-'。 – MicroVirus

回答

1

这可能是您的情况属于简单的图案,其中你的单子,如果下面的形式:

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

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

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

,你可能需要使用此功能在实现时(>> =):

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

如果你的单子类型的形式为:

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) 
2

case声明和语法错误,尽管如此,这个定义实际上是明显无意义的,因为在do-block中的绑定被转换为使用>>=。所以你现有的代码已经定义了m >>= f = m >>= \a -> ...,这是一个无限循环和一个空间泄漏。