我正在做一个haskell练习,关于定义一个函数accumulate ::IO一个-> IO a,它执行一系列交互并将它们的结果累积到一个列表中。
让我困惑的是如何表达一个IO列表?(动作:动作)??
如何使用IO编写递归代码??
这是我的代码,但它们存在一些问题...
accumulate :: [IO a] -> IO [a]
accumulate (action:actions) = do
value <- action
list <- accumulate (action:actions)
return (convert_to_list value list)
convert_to_list:: Num a =>a -> [a]-> [a]
convert_to_list a [] = a:[]
convert_to_list x xs = x:xs发布于 2012-09-30 15:20:47
您正在尝试实现的是来自Control.Monad的sequence。
为了让你找到答案而不是给出答案,试着在hoogle上搜索[IO a] -> IO [a] (当你选择一个函数时,页面右侧会有一个源代码链接)。
试着在你的代码中看看当动作列表为空列表时会发生什么,看看sequence会做些什么来解决这个问题。
发布于 2012-09-30 15:20:37
在Control.Monad中已经有了这样的函数,它叫做sequence (不,你不应该看它)。您应该注明在命名过程中做出的重要决定。从技术上讲,[IO a]没有说明这些Monad应该以什么顺序相互连接,但名称sequence赋予了顺序连接的含义。
至于解决你的问题。我建议多看看类型,并采纳@sacundim的建议。在GHCi ( Glasgow Haskell Compiler的解释器)中,有一种非常好的方法来检查类型,从而理解表达式(:t (:)将返回(:) :: a -> [a] -> [a],这应该会提醒你自己的函数,但类型限制较少)。
首先,我将尝试通过更简单的示例来查看您所展示的内容。
data MyWrap a = MyWrap a
accumulate :: [MyWrap a] -> MyWrap [a]
accumulate (action:actions) = MyWrap (convert_to_list value values) where
MyWrap value = action -- use the pattern matching to unwrap value from action
-- other variant is:
-- value = case action of
-- MyWrap x -> x
MyWrap values = accumulate (action:actions)我犯了和你故意犯的相同的错误,但差别很小(values是一个提示)。正如您可能已经被告知的那样,您可以尝试通过内联适当的函数定义来解释任何程序。即匹配等号(=)左侧的定义,并将其替换为右侧。在你的例子中,你有无限的循环。试着在这个样本上解决它,或者你的,我想你会明白的(顺便说一句,你的问题可能只是一个打字错误)。
更新:当你的程序在运行时出现关于模式匹配的消息时,不要害怕。只需考虑将函数调用为accumulate []时的情况
发布于 2012-09-30 15:17:56
您可能正在寻找映射[m a] -> m [a]的sequence函数
https://stackoverflow.com/questions/12659076
复制相似问题