3

我有这种格式的计算:s -> a -> ss某些状态的类型在哪里。这样一个函数的结果也是下一次求值的状态。例如,

appendInt :: String -> Int -> String
appendInt s i = s ++ (show i)

然后,appendInt "Int: " 1将给予"Int: 1",同时(appendInt $ appendInt "Int: 1") 2将给予"Int: 12"。但是,我找不到将这种计算放入StateMonad 的方法。

第一个猜测是s -> (s,s),但随后a无法传入。然后,我尝试了 ,但(a -> s) -> (s, a -> s)又一次无法获得。不起作用,因为是输入而不是输出。sas -> (a,s)a

那么我应该如何包装这个计算呢?State单子适合这个吗?

4

2 回答 2

7

您可以State很好地使用,甚至更好地使用Writer

import Control.Monad.Writer
import Control.Monad.State

appendInt :: Int -> Writer String ()
appendInt i = tell $ show i

appendInt' :: Int -> State String ()
appendInt' i = modify (++ show i)

main = do print . execWriter $ do
            tell "Int: "
            appendInt 1
            appendInt 2
          print . flip execState "Int: " $ do
            appendInt' 1
            appendInt' 2
于 2015-10-08T07:16:49.570 回答
3

当然可以,例如这样:

appendIntM :: MonadState String m => Int -> m ()
appendIntM i = modify $ flip appendInt i

如果您使参数的顺序更“传统”,那将只是与modify.

Live On Coliru

于 2015-10-08T06:28:08.380 回答