Ber*_*ian 2 haskell state-monad
我正在尝试使用State monad进行一些计算,同时还要对其进行更改。我已经实现的情况下Applicative,Monad和Functor以及get和put,modify等我不明白的脱糖do块。您如何同时提供状态和状态转换器?
实用程序
get::State s s
get=State $ \s ->(s,s)
put::s->State s ()
put x=State $ \_ -> ((),x)
modify::(s->s)->State s ()
modify f=get>>= \x -> put (f x)
evalState::State s a->s->a
evalState act =fst . run act
execState::State s a->s->s
execState act=snd.run act
Run Code Online (Sandbox Code Playgroud)
码
module Env where
import State
import System.Directory
import Control.Monad
data Env=Env{
envName::String,
fileNames::[String]
}
instance Show Env where
show Env{envName=x,fileNames=xs} = "{ envName:"++x++" , files: ["++foldr (\t y-> t++","++y) "" xs ++"] }"
initEnv::IO Env
initEnv=do
name<- getLine
names<- getCurrentDirectory>>=listDirectory
return Env{envName=name,fileNames=names}
changeName::String->State Env ()
changeName (y:ys)=State $ \ (Env (x:xs) ls) -> ((),Env (y:xs) ls)
toStats::State Env String
toStats= State $ \env -> (show env,env)
useEnv::IO (State Env String)
useEnv=do
liftM put initEnv --passes state transformer
liftM changeName getLine --passes strate transformer
print . evalState . toStats --how do i supply both ?
return toStats
Run Code Online (Sandbox Code Playgroud)
如您所见,在我的最后一行中,我正在初始化状态转换器,并将其传递给进行进一步的更改...,直到到达evalState并想要使用它为止。在这种情况下,我不知道如何为状态和变压器供电。
PS变压器,我的意思是包装s->(a,s)
您的代码不使用任何monad转换器。我想你只是在找
useEnv :: IO ()
useEnv = do
env <- initEnv
name <- getLine
let actions = do
changeName name
toStats
let str = evalState actions env
putStrLn str
Run Code Online (Sandbox Code Playgroud)
即State从IOdo块内部运行动作。