我有一个模块,其中有一个全局环境(定义某些约束,例如邻居IP地址等)。通过调用初始化函数来创建和初始化。在调用这些约束时,许多后续函数应该使用这些约束。
虽然在原则上我理解读者的独白是什么,但我不太确定如何将它应用于我的问题,尤其是我的问题。
myinitial :: arg1 -> arg1 -> IOString )中读取的,其中arg1和arg2随后成为后续函数通过read (?)访问的全局不可变数据。recvFrom s arg1,其中arg1是来自我的环境的全局不可变数据。或if arg2 > arg1 then ... else ...当然,我可以创建一个配置文件,但我觉得配置文件会带来很大的灵活性。
编辑我对ask的理解,但是不应该有额外的“无点的类”方式,这样如果函数签名已经定义好了,就可以省略全局/环境不变的内容了吗?我将如何,即需要重构我的如果-然后-其他应用这。
发布于 2012-06-13 08:17:20
这里有一个例子,可以澄清问题。首先,您需要导入Reader模块:
import Control.Monad.Reader现在,让我们定义一些数据结构(我们将使用它来保存名称和年龄)。
data Config = Config { name :: String, age :: Int }现在定义一个在Reader中工作的函数(它的类型是Reader Config (String, Int),但我们不需要指定它--可以推断)。这个函数所做的就是请求环境(类型为Config),然后提取字段并对它们做一些事情。
example = do
c <- ask
return ("Hello " ++ name c, 2 * age c)现在我们把所有的东西放在一个程序里。do块后的前四行允许用户输入他们的姓名和年龄。然后,我们使用用户的输入构建一个Config结构(我们必须使用read将变量_age (即String )转换为一个Int,以便我们可以将它提供给Config构造函数),并使用runReader函数使用这个环境执行example。最后,我们利用这个计算结果生成一些输出。
main = do
putStrLn "Enter your name:"
_name <- getLine
putStrLn "Enter your age:"
_age <- getLine
let config = Config _name (read _age)
let result = runReader example config
putStrLn $ fst result
putStrLn $ "Twice your age is: " ++ show (snd result)发布于 2012-06-13 00:29:50
大多数问题可以通过检查问和runReader函数的类型和文档来回答。
首先,ask
ask :: Reader m r => m r这将返回封装在monad中的底层只读数据。酷,所以当您想要将它与其他函数一起使用时,就会这样进入状态,在上面的示例中:
do x <- ask
recvFrom s x(当然,这取决于recvFrom的类型)
接下来是runReader,这就是您所讨论的初始数据。它基本上只是使用给出的数据来运行Reader计算:
runReader :: Reader r a -> r -> a这意味着:使用r类型的只读数据(第二个参数)运行计算(第一个参数)。最后,它将返回第一个参数a的结果类型。在您的例子中,这可能看起来是:
result = runReader computationUsingArg1Arg2 (arg1, arg2)然后在computationUsingArg1Arg2内部,您可以通过ask阅读arg1和arg2。
https://stackoverflow.com/questions/11006364
复制相似问题