结合 IO monad 和 State Monad 的例子
combining IO monad with State Monad in example
我为语句创建了简单的求值器。
我想使用变形金刚来做到这一点 - 将 IO monad 与 State 混合。
有人可以解释该怎么做吗?这是我无法处理的东西 - 变形金刚。
execStmt :: Stmt -> State (Map.Map String Int) ()
execStmt s = case s of
SAssigment v e -> get >>= (\s -> put (Map.insert v (fromJust (runReader (evalExpM e) s)) s))
SIf e s1 s2 -> get >>= (\s -> case (fromJust (runReader (evalExpM e) s)) of
0 -> execStmt s2
_ -> execStmt s1
)
SSkip -> return ()
SSequence s1 s2 -> get >>= (\s -> (execStmt s1) >>= (\s' -> execStmt s2))
SWhile e s1 -> get >>= (\s -> case (fromJust (runReader (evalExpM e) s)) of
0 -> return ()
_ -> (execStmt s1) >>= (\s' -> execStmt (SWhile e s1)))
execStmt' :: Stmt -> IO ()
execStmt' stmt = putStrLn $ show $ snd $ runState (execStmt stmt) Map.empty
这是一个基本的程序大纲
newtype StateIO s a = SIO {runSIO :: s -> IO (a, s)}
put :: s -> StateIO s ()
put s' = SIO $ \_s -> return ((), s')
liftIO :: IO a -> StateIO s a
liftIO ia = SIO $ \s -> do
a <- ia
return (a, s)
instance Functor (StateIO s) where
fmap ab (SIO sa) = SIO $ \s -> do
(a, s') <- sa s
let b = ab a
return (b, s')
instance Applicative (StateIO s) where
pure a = SIO $ \s -> return (a, s)
(SIO sab) <*> (SIO sa) = SIO $ \s -> do
(ab, s' ) <- sab s
(a , s'') <- sa s'
let b = ab a
return (b, s')
StateIO s a
是接受输入状态(s
类型)的东西,returns 是一个 IO 动作,用于产生 a
类型的东西以及新状态。
要检查是否理解,请执行以下操作
- 写一个
get :: StateIO s s
的值来检索状态。
- 为
Monad (StateIO s)
编写一个实例(它将类似于上面的代码)。
- 最后,这是理解变形金刚的一大步,就是定义
newtype StateT m s a = StateT {run :: s -> m (a, s)}
,并将上面的代码翻译成那个(使用约束 Monad m
)。这将向您展示 monad 转换器的工作原理。
我为语句创建了简单的求值器。
我想使用变形金刚来做到这一点 - 将 IO monad 与 State 混合。
有人可以解释该怎么做吗?这是我无法处理的东西 - 变形金刚。
execStmt :: Stmt -> State (Map.Map String Int) ()
execStmt s = case s of
SAssigment v e -> get >>= (\s -> put (Map.insert v (fromJust (runReader (evalExpM e) s)) s))
SIf e s1 s2 -> get >>= (\s -> case (fromJust (runReader (evalExpM e) s)) of
0 -> execStmt s2
_ -> execStmt s1
)
SSkip -> return ()
SSequence s1 s2 -> get >>= (\s -> (execStmt s1) >>= (\s' -> execStmt s2))
SWhile e s1 -> get >>= (\s -> case (fromJust (runReader (evalExpM e) s)) of
0 -> return ()
_ -> (execStmt s1) >>= (\s' -> execStmt (SWhile e s1)))
execStmt' :: Stmt -> IO ()
execStmt' stmt = putStrLn $ show $ snd $ runState (execStmt stmt) Map.empty
这是一个基本的程序大纲
newtype StateIO s a = SIO {runSIO :: s -> IO (a, s)}
put :: s -> StateIO s ()
put s' = SIO $ \_s -> return ((), s')
liftIO :: IO a -> StateIO s a
liftIO ia = SIO $ \s -> do
a <- ia
return (a, s)
instance Functor (StateIO s) where
fmap ab (SIO sa) = SIO $ \s -> do
(a, s') <- sa s
let b = ab a
return (b, s')
instance Applicative (StateIO s) where
pure a = SIO $ \s -> return (a, s)
(SIO sab) <*> (SIO sa) = SIO $ \s -> do
(ab, s' ) <- sab s
(a , s'') <- sa s'
let b = ab a
return (b, s')
StateIO s a
是接受输入状态(s
类型)的东西,returns 是一个 IO 动作,用于产生 a
类型的东西以及新状态。
要检查是否理解,请执行以下操作
- 写一个
get :: StateIO s s
的值来检索状态。 - 为
Monad (StateIO s)
编写一个实例(它将类似于上面的代码)。 - 最后,这是理解变形金刚的一大步,就是定义
newtype StateT m s a = StateT {run :: s -> m (a, s)}
,并将上面的代码翻译成那个(使用约束Monad m
)。这将向您展示 monad 转换器的工作原理。