如何编写状态Monad的实例

3

我对 Haskell 中的 Monad 很陌生,正在尝试通过创建实例来增加我的知识。但是,在处理该实例时遇到了一些错误,已经花费了一定时间,仍然不确定问题出在哪里。希望得到帮助和解释。这是我目前所做的,有任何想法或建议吗?

newtype ST b = S (Int -> (b, Int))
runState :: ST b  -> Int -> (b, Int)
runState (S b) st = b st 

instance Monad ST where 
return :: b -> ST b
return x = S (\st -> (x, st))       the new state with a b 

(>>=) :: ST b -> (b -> ST c) -> ST c
c >>= c' = S (\st1 ->
                let (b, st2) = runState c st1
                    (c, st3) = runState (c' b) st2
                in  (c, st3))

在同一声明中不应该为不同的变量使用相同的变量名,就像这里所做的一样:c >>= ...(c, st3) = ... - md2perpe
@md2perpe 哦,等等,那是因为我在绑定函数中使用了C语言,所以下一行我应该使用其他语言对吧? (>>=) :: ST b -> (b -> ST c) -> ST c - tDownUnder
(>>=) :: ST b -> (b -> ST c) -> ST c这一行中的cc >>= ...(c, st3) = ...中的c不会发生冲突,因为在第一种情况下它是一个类型变量,而在后一种情况下它是一个普通(值)变量。我所指的是你在>>=左边有一个c,然后在(c, st3) = ...中引入另一个c。将后者重命名为t'' - md2perpe
Monad and others can be derived via State Int: newtype ST b = S (Int -> (b, Int)) deriving (Functor, Applicative, Monad, MonadFix) via State Int - Iceland_jack
1个回答

1

您可能还需要为Applicative和Functor提供实现:

import Control.Applicative
import Control.Monad (liftM, ap)

newtype ST b = S (Int -> (b, Int))
runState :: ST b  -> Int -> (b, Int)
runState (S b) st = b st 

instance Monad ST where 
  -- return :: b -> ST b
  return x = S (\st -> (x, st))      -- takes in the current state and returns the new state with a b 
  
  -- (>>=) :: ST b -> (b -> ST c) -> ST c
  c >>= c' = S (\st1 ->
                let (b, st2) = runState c st1
                    (c'', st3) = runState (c' b) st2
                in  (c'', st3))


instance Applicative ST where
  pure = return
  (<*>) = ap


instance Functor ST where
  fmap = liftM

我发现这里

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接