如何将 Reader Monad 与 (Int -> Int) 一起使用?
How to use the Reader Monad with (Int -> Int)?
我想学习如何使用 Reader Monad。遗憾的是只有少量示例代码可用
我想创建一个 Reader,其中环境和检索值是 Int
。我这样定义类型:
type IntRead = Reader Int Int
我试过的代码是这样的:
addStuff :: Reader Int Int
addStuff = do
a <- (*2)
b <- (+10)
return (a+b)
我得到一个错误,因为 ReaderT
是预期的。如何使用 Reader Monad 创建类似 addStuff
的函数?我应该在哪里提供这个功能的环境?
您可以将函数转换为 reader 并返回这两个同构:
reader :: (r -> a) -> Reader r a
runReader :: Reader r a -> r -> a
例如
addStuff :: Reader Int Int
addStuff = do
a <- reader (*2)
b <- reader (+10)
return (a+b)
然后您可以使用 runReader addStuff 5
.
测试您的代码
这可以用于学习目的。对于更严肃的代码,您不应该过多地使用同构,而应该依赖 ask
或 asks
。例如
addStuff :: Reader Int Int
addStuff = do
x <- ask -- fetch the implicit Int value
let a = (*2) x
b = (+10) x
return (a+b)
或者更好
addStuff :: Reader Int Int
addStuff = do
a <- asks (*2) -- fetch the implicit Int value, and apply the function
b <- asks (+10)
return (a+b)
或者,更好的是,使用应用样式:
addStuff :: Reader Int Int
addStuff = (+) <$> asks (*2) <*> asks (+10)
reader 抽象的重点是不考虑底层功能。您可以假装可以访问只读变量,该变量可通过 ask
原语访问。
通常,只有在最后一步,您才使用 runReader
来实际使用您的 monadic reader 操作。
我想学习如何使用 Reader Monad。遗憾的是只有少量示例代码可用
我想创建一个 Reader,其中环境和检索值是 Int
。我这样定义类型:
type IntRead = Reader Int Int
我试过的代码是这样的:
addStuff :: Reader Int Int
addStuff = do
a <- (*2)
b <- (+10)
return (a+b)
我得到一个错误,因为 ReaderT
是预期的。如何使用 Reader Monad 创建类似 addStuff
的函数?我应该在哪里提供这个功能的环境?
您可以将函数转换为 reader 并返回这两个同构:
reader :: (r -> a) -> Reader r a
runReader :: Reader r a -> r -> a
例如
addStuff :: Reader Int Int
addStuff = do
a <- reader (*2)
b <- reader (+10)
return (a+b)
然后您可以使用 runReader addStuff 5
.
这可以用于学习目的。对于更严肃的代码,您不应该过多地使用同构,而应该依赖 ask
或 asks
。例如
addStuff :: Reader Int Int
addStuff = do
x <- ask -- fetch the implicit Int value
let a = (*2) x
b = (+10) x
return (a+b)
或者更好
addStuff :: Reader Int Int
addStuff = do
a <- asks (*2) -- fetch the implicit Int value, and apply the function
b <- asks (+10)
return (a+b)
或者,更好的是,使用应用样式:
addStuff :: Reader Int Int
addStuff = (+) <$> asks (*2) <*> asks (+10)
reader 抽象的重点是不考虑底层功能。您可以假装可以访问只读变量,该变量可通过 ask
原语访问。
通常,只有在最后一步,您才使用 runReader
来实际使用您的 monadic reader 操作。