Haskell折叠嵌套列表

时间:2012-02-02 20:10:56

标签: haskell

目前我正在搞乱Haskell。我对Haskell(以及一般的函数式语言)的了解仍然很少,但我正在研究它。 真正困扰我的是一个(我认为)简单的任务:折叠嵌套列表,每个深度折叠一次。

fcalc = foldr (\x y -> (foldr (**) 1 x) * (foldr (**) 1 y)) [1.0, 1.0] [[2.0, 3.0], [4.0, 5.0]]

它应该做什么:2 ^ 3 * 4 ^ 5其中^由λ内部折叠完成。可悲的是,它不起作用。

Occurs check: cannot construct the infinite type: t0 = [t0]
In the third argument of `foldr', namely `y'

我已经读过一些关于给定的“无限类型”错误,主要表明一个变量用作例如元素,而它是一个列表而不是。这让我想到外部折叠的第二个参数作为问题,但没有成功。 我只是不明白。 :/

2 个答案:

答案 0 :(得分:4)

你的问题是你试图在你的累加器内进行a^b计算,同时也在每个元素上进行计算。你真正想要的是像

fcalc = foldr (\x y -> (foldr (**) 1 x) * y) 1 [[1.0, 1.0], [2.0, 3.0], [4.0, 5.0]]

请记住,foldr的每个步骤的输出都作为下一步的第二个参数插入(例如,在这种情况下为y变量)。由于您的foldr步骤返回了一个数字,y变量已经是一个数字,因此您无法折叠它。

答案 1 :(得分:1)

不是您问题的答案,而是解决问题的另一种方法:

haskell> sum $ map ((**) <$> (!! 0) <*> (!! 1)) xs
1032.0

或者,如果你对pointfree感到不舒服:

haskell> sum $ map (\x -> let (a:b:_) = x in a ** b) xs
1032.0