Я пытаюсь использовать Государственную монаду, чтобы сделать некоторые вычисления, также изменяя ее. Я реализовал экземпляры Applicative
, Monad
и Functor
, а также get
и put
, modify
и т. Д.
Я не понимаю desugaring блока do
. Как вы поставляете и штат, и трансформатор состояния?
Utils
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
Код
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
Как вы можете видеть, в моей последней строке я инициализирую преобразователь состояния и передаю его для дальнейшего изменения ... пока не достигну evalState
и не захочу его использовать. В этом случае я не знаю, как поставить состояние и трансформатор.
P.S Под трансформатором я подразумеваю оболочку над s->(a,s)