Jan*_*n v 1 monads state haskell
我们有以下类型的任务给出
newtype Trans state a = T {run :: state -> (a,state)}
type Stack a = Trans [Int] a
Run Code Online (Sandbox Code Playgroud)
我想要的是编写一个函数1.按下将一个Integer放在堆栈上2.弹出以返回并删除最高的对象
我试图谷歌通过状态monads来理解它们,我得到了概念,但我无法用给定的类型结构实现它.
流行和推送相当简单:
push :: Int -> Stack ()
push x = T { run = \st -> ((), x : st) }
pop :: Stack (Maybe Int)
pop = T
{ run = \st -> case st of
(x : xs) -> (Just x, xs)
_ -> (Nothing, st)
}
Run Code Online (Sandbox Code Playgroud)
pop是类型,Maybe Int因为堆栈可以为空.在那种情况下,我们回来Nothing.但我们能做些什么呢?嗯,没有一个Monad实例并不多.我们来做一个.我们首先需要Functor和Applicative实例:
instance Functor (Trans st) where
fmap f (T r) = T
{ run = \st ->
let (result, state) = r st
in (f result, state)
}
instance Applicative (Trans st) where
pure a = T { run = \st -> (a, st) }
(<*>) (T fr) (T r) = T
{ run = \st ->
let (result, state) = r st
(f, nextState) = fr state
in (f result, nextState)
}
instance Monad (Trans a) where
(>>=) (T r) f = T
{ run = \st ->
let (result, state) = r st
in run (f result) state
}
Run Code Online (Sandbox Code Playgroud)
它给了我们什么?我们终于可以用我们pop和push功能:
simpleStack :: Stack Int
simpleStack = do
push 10
push 20
push 30
Just x <- pop
return x
Run Code Online (Sandbox Code Playgroud)
我们可以这样测试:
main :: IO ()
main = putStrLn $ show $ fst $ run simpleStack []
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
99 次 |
| 最近记录: |