【发布时间】:2014-06-11 08:51:40
【问题描述】:
我正在尝试从列表中选择一个随机元素,但这会使函数不纯,因此无法编译。我应该怎么做才能让递归函数接受一个 IO 动作?
build :: Jabberwocky Integer String Syllables -> String
build (Jabberwocky 0 body syl) = body
build (Jabberwocky len body syl)
| syl == Middle = build (Jabberwocky (len - 1) (body ++ (rand middle) ) Consonant)
| syl == Consonant = build (Jabberwocky (len - 1) (body ++ (rand consonant)) Vowel)
| syl == Vowel = build (Jabberwocky (len - 1) (body ++ (rand vowel) ) Consonant)
| syl == Ending = build (Jabberwocky (len - 1) (body ++ (rand ending) ) Vowel)
where
rand = getStdRandom (randomR (1,6))
【问题讨论】:
-
您可以以纯粹的方式生成随机数,根本不需要
IO。你只需要传递你自己的生成器对象而不是使用全局对象。如果您坚持使用IO,那么您的签名应该显示它(但我不会这样做)。 -
您能详细说明一下吗?到目前为止,我寻找的答案恰恰相反。 stackoverflow.com/questions/2926267/…
-
不相反,正是我的意思。
Jabberwocky ... -> String是一个纯函数。你不能在里面使用IO。您需要将函数更改为不纯函数 (Jabberwocky ... -> IO String) 或停止使用全局随机数生成器。 -
抱歉这个菜鸟问题。我还是很困惑。如何用 monad 编写函数?