[英]Manipulating Haskell Monad State
有点类似于这个问题,我试图弄清楚如何在 Haskell Monad 状态中移动。 团队中的每个Employee
都被相应的Employee'
替换,同时保持一些简单的状态。 这是代码:
module Main( main ) where
import Control.Monad.State
data Employee = EmployeeSW Int Int | EmployeeHW Int String deriving ( Show )
data Employee' = EmployeeSW' Int | EmployeeHW' String deriving ( Show )
scanTeam :: [Employee] -> State (Int,Int) [Employee']
scanTeam [ ] = return []
scanTeam (p:ps) = scanEmployee p -- : scanTeam ps ???
scanEmployee :: Employee -> State (Int,Int) Employee'
scanEmployee (EmployeeSW id s) = do
(num,raise) <- get
put (num+1,raise)
return (EmployeeSW' (s+raise))
scanEmployee (EmployeeHW id s) = do
(num,raise) <- get
put (num+1,raise)
return (EmployeeHW' (s++(show raise)))
startState = (0,3000)
t = [(EmployeeHW 77 "Hundred"),(EmployeeSW 66 500),(EmployeeSW 32 200)]
main = print $ evalState (scanTeam t) startState
我想最终将scanEmployee p
与scanTeam ps
连接scanEmployee p
,所以我尝试提取scanEmployee p
各个部分,并以某种方式将它们与scanTeam ps
粘合在一起。 到目前为止,我失败得很惨。 实际上,我什至不确定状态是否可以在它们之间移动(?)。
由于State
是一个 monad,您可以使用do
表示法来定义State
计算。 ( State
的Monad
实例会检测状态,因此do
块中一个语句的结束状态成为下一个语句的开始状态。)
因此,在do
块中,我将:
Employee
以获得一个新的Employee
State
FUL计算。scanTeam :: [Employee] -> State (Int,Int) [Employee']
scanTeam [ ] = return []
scanTeam (p:ps) = do
newP <- scanEmployee p
newPs <- scanTeam ps
return (newP:newPs)
事实证明,“在 monadic 上下文中map
”通常非常有用,因此它作为mapM :: Monad m => (a -> mb) -> [a] -> m [b]
( aka traverse :: (Traversable t, Applicative f) => (a -> fb) -> ta -> f (tb)
,如果你准备好进入兔子洞的话)。
scanTeam = mapM scanEmployee
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.