Haskell使用foldr

时间:2014-03-10 19:50:17

标签: haskell fold

嗨,我是Haskell的新手,我有点失落。我已经得到了这个,但无法解决这个问题。


仅使用foldr,布尔操作(||)False定义一个函数

or_list :: [Bool] -> Bool

这样

or_list [b1, b2,...,bn] = b1 || b2 ||...|| bn

请注意

or_list [] = False

我想出了类似的东西

or_list :: [Bool] -> Bool
or_list [0..n] = foldr False (||) [0..n] 

但是我真的不知道foldr是如何运作的。如果有人能指出我走正确的道路,那将是一个很大的帮助。

3 个答案:

答案 0 :(得分:11)

你几乎得到了正确的定义,但你的语法有点偏。你不能像

这样的模式匹配
or_list [0..n] = ...

这只是无效的语法。事实上,你根本不需要模式匹配,你可以做到

or_list bs = foldr False (||) bs

通过查看foldr的类型可以揭示下一个问题:

foldr :: (Bool -> Bool -> Bool) -> Bool -> [Bool] -> Bool
-- Simplified from its more general type

请注意,它的第一个参数是一个带有两个布尔值的函数,第二个参数只是一个布尔值。

foldr False (||) bs

False不是函数,(||)不是布尔值。如果你交换它们就会得到

foldr (||) False bs

然后你的定义是正确的!


这是如何工作的?折叠是简单递归的推广,通常你有一个函数,你正在应用一个也取决于最后计算的值的参数。这些类型的递归对于将值列表转换为单个值非常有用。 foldr的定义非常简单,我认为它有助于解释折叠如何工作

foldr f initial [] = initial
foldr f initial (x:xs) = f x (foldr f initial xs)

因此,如果我们要插入一些值并展开它

  foldr (||) False [False, False, True]
= False || (foldr (||) False [False, True])
= False || (False || (foldr (||) False [True]))
= False || (False || (True || (foldr (||) False [])))
= False || (False || (True || (False)))
= False || (False || True)
= False || True
= True

另一种看待它的方法是它在列表中用:替换f[] initial,所以如果你有

False : False : True : []

您向其foldr (||) False申请,您将:替换||[]替换为False,关联权利{{1} {}}}的一部分,所以

r

这与我们上面的扩展相同。 foldr在相反的关联中起作用,因此False || (False || (True || (False))) 看起来像

foldl

因此,差异基本上是初始值停留在何处以及括号所在的位置。

答案 1 :(得分:2)

Prelude中的foldr函数是一个高阶函数,它接受f类型的函数(a -> b -> b)并将其应用于类型[a]的列表,从而产生类型列表[b]。它还需要一个应用于z

的第一个应用程序的初始元素f

象征性地在伪代码中这样减少:

foldr f z [a,b,c,...,n] == f a (f b (f c (... (f n z)...)))

所以对于你的功能,你需要这样的东西:

foldr (||) False [a,b,c,...,n] = a || (b || (c ... (n || False)))

希望有助于直觉的折叠。

答案 2 :(得分:0)

您有以下定义:

or_list :: [Bool] -> Bool

右。

让我们看看第二行:

or_list [0..n] = foldr False (||) [0..n]

所以实际上这非常接近所需,但有几个问题。首先让我们来看看:

or_list [0..n] = ...

这可能应该是这样的:

or_list (x:xs) = ...

请参阅this了解原因。接下来,我会给你一些提示。密切注意foldr的签名,你没有给出正确的参数顺序。此外,您需要处理空列表[]的情况,该列表实际上是在我给您的链接中提到的。