任务提供了以下类型
newtype Trans state a = T {run :: state -> (a,state)}
type Stack a = Trans [Int] a
我要写的是函数 1.推动将整数放入堆栈 2.弹出以返回并删除最高的对象
我试图通过状态单子查询Google以了解它们,但我得到了这个概念,但是我无法使用给定的类型结构来实现它。
答案 0 :(得分:5)
弹出和推送非常简单:
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)
}
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
}
它给我们带来什么?我们终于可以使用我们的pop
和push
函数了:
simpleStack :: Stack Int
simpleStack = do
push 10
push 20
push 30
Just x <- pop
return x
我们可以这样测试:
main :: IO ()
main = putStrLn $ show $ fst $ run simpleStack []