ReaderT静态环境
ReaderT static environment
Declaration of the ReaderT
monad transformer, which adds a static environment to a given monad.
向给定的 monad 添加静态环境是什么意思?
有人建议这与另一个问题重复。我相信这个问题是独一无二的,因为我在问拥有静态环境意味着什么,而且我的问题与 ReaderT 有关。即使和Reader很像,还是有区别的
这意味着无法更新环境:您只能从中读取(因此得名ReaderT
)。这与像 StateT
这样的 monad 转换器形成对比,后者为您提供了一个可以读写的环境。
在 reader monad 中,您可以使用 ask
函数到达环境:
ask :: Monad m => ReaderT r m r
在状态 monad 中,你有一个类似的读取函数,叫做 get
as well as another function which writes to the state called put
:
get :: Monad m => StateT s m s
put :: Monad m => s -> StateT s m ()
例子
这是 ReaderT
和 StateT
的用法示例。让我们假设我的底层 monad 将是 IO
这样我就可以打印东西了。
这里的人为示例是一个数字猜测程序 - 环境只是您试图猜测的数字(所以 Int
)。 guess
取一个数字,检查这个数字是否与环境中的数字相同。如果没有,它会在屏幕上打印一条消息。无论哪种情况,它 returns 您的猜测是否成功。
guessReader :: Int -> ReaderT Int IO Bool
guessReader guess = do
actual <- ask
if guess == actual
then return True
else do
lift $ putStrLn ("The number was " ++ show actual)
return False
但是,假设现在您想要一种方法来改变您在猜测后随机尝试猜测的数字。然后,由于你需要改变环境,你将需要使用 StateT
.
import System.Random (randomRIO)
guessState :: Int -> StateT Int IO Bool
guessState guess = do
actual <- get
if guess == actual
then return True
else do
lift $ putStrLn ("The number was " ++ show actual)
newActual <- lift $ randomRIO (0,10)
put newActual
return False
然后,如果您多次 运行 reader 版本,请注意您尝试猜测的值永远不会改变。状态版本不是这种情况,每次你猜错都会重置为一个新数字:
ghci> runReaderT (guessReader 3 >> guessReader 4 >> guessReader 5) 5
The number was 5
The number was 5
True
ghci> evalStateT (guessState 3 >> guessState 4 >> guessState 5) 5
The number was 5
The number was 6
The number was 2
False
Declaration of the
ReaderT
monad transformer, which adds a static environment to a given monad.
向给定的 monad 添加静态环境是什么意思?
有人建议这与另一个问题重复。我相信这个问题是独一无二的,因为我在问拥有静态环境意味着什么,而且我的问题与 ReaderT 有关。即使和Reader很像,还是有区别的
这意味着无法更新环境:您只能从中读取(因此得名ReaderT
)。这与像 StateT
这样的 monad 转换器形成对比,后者为您提供了一个可以读写的环境。
在 reader monad 中,您可以使用 ask
函数到达环境:
ask :: Monad m => ReaderT r m r
在状态 monad 中,你有一个类似的读取函数,叫做 get
as well as another function which writes to the state called put
:
get :: Monad m => StateT s m s
put :: Monad m => s -> StateT s m ()
例子
这是 ReaderT
和 StateT
的用法示例。让我们假设我的底层 monad 将是 IO
这样我就可以打印东西了。
这里的人为示例是一个数字猜测程序 - 环境只是您试图猜测的数字(所以 Int
)。 guess
取一个数字,检查这个数字是否与环境中的数字相同。如果没有,它会在屏幕上打印一条消息。无论哪种情况,它 returns 您的猜测是否成功。
guessReader :: Int -> ReaderT Int IO Bool
guessReader guess = do
actual <- ask
if guess == actual
then return True
else do
lift $ putStrLn ("The number was " ++ show actual)
return False
但是,假设现在您想要一种方法来改变您在猜测后随机尝试猜测的数字。然后,由于你需要改变环境,你将需要使用 StateT
.
import System.Random (randomRIO)
guessState :: Int -> StateT Int IO Bool
guessState guess = do
actual <- get
if guess == actual
then return True
else do
lift $ putStrLn ("The number was " ++ show actual)
newActual <- lift $ randomRIO (0,10)
put newActual
return False
然后,如果您多次 运行 reader 版本,请注意您尝试猜测的值永远不会改变。状态版本不是这种情况,每次你猜错都会重置为一个新数字:
ghci> runReaderT (guessReader 3 >> guessReader 4 >> guessReader 5) 5
The number was 5
The number was 5
True
ghci> evalStateT (guessState 3 >> guessState 4 >> guessState 5) 5
The number was 5
The number was 6
The number was 2
False