【发布时间】:2014-04-29 14:27:44
【问题描述】:
我正在尝试在 Haskell 中编写一个函数,该函数将弹出一些已序列化为字符串列表的项目。 (这个列表代表一个文本文件的行——一行不一定是一项)
函数以另一个函数作为参数调用。此函数将弹出一个项目,并返回一个包含该项目和文本其余部分的元组。该函数应该递归地执行此操作 n 次,每次将结果添加一个列表。它返回此列表以及文本的其余部分,以用于进一步解析。
popN :: Integer -> [String] -> ([String]-> (a, [String])) -> ([a], [String])
popN n txt fun | n == 0 = ([], txt)
| n /= 0 = do
let (tp, newtxt) = fun txt
let newnum = n - 1
let (rest, after) = popN newnum newtxt fun
return (tp : rest, after)
当我尝试编译此代码时,我收到以下错误:
Couldn't match the expected type '[String]' with actual type '([a], [String])'
In the first argument of 'return', namely '(tp : rest, after)'
实际类型,([a], [String]) 是我期望的类型。但是,我不明白为什么 [String] 是预期的类型。有人可以向我解释为什么 GHC 期望这个函数返回一个 [String] 吗?
提前感谢您的帮助。
【问题讨论】:
-
do表示法意味着您的返回类型是一个 monad,例如[a]、IO a、Maybe a等。元组本身不构成一个 monad,所以您不能将do表示法或return与它们一起使用。 -
很好的问题标题!
标签: haskell recursion types infinite