我有这种格式的计算:s -> a -> s
,其中s
是某种状态的类型。这种功能的结果也是下一次评估的状态。例如,
appendInt :: String -> Int -> String
appendInt s i = s ++ (show i)
然后,appendInt "Int: " 1
将提供"Int: 1"
,而(appendInt $ appendInt "Int: 1") 2
将提供"Int: 12"
。但是,我找不到将这种计算放在State
Monad中的方法。
第一个猜测是s -> (s,s)
,但后来却无法传递a
。然后,我尝试了(a -> s) -> (s, a -> s)
,但是如果没有{s
则不可能a
1}}。 s -> (a,s)
无效,因为a
是输入而非输出。
那么我该如何包装这个计算呢? State
monad是否适用于此?
答案 0 :(得分: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
答案 1 :(得分:3)
当然有可能,例如:
appendIntM :: MonadState String m => Int -> m ()
appendIntM i = modify $ flip appendInt i
如果您使参数的顺序更多"传统",它只会是modify
的组合。