您可以使用以下两种同构将函数转换为读取器并返回:
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
or 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)
读者抽象的重点不是考虑底层功能。您可以假装可以访问只读变量,该变量可通过ask
原语访问。
通常,仅在您runReader
实际使用单子阅读器操作的最后一步。