繁体   English   中英

Haskell使用foldr

[英]Haskell using foldr

嗨,我是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工作原理。 如果有人能指出我走正确的道路,那将是一个很大的帮助。

你几乎得到了正确的定义,但你的语法有点偏。 你不能有类似的模式匹配

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应用于它,你将替换每个: by || []False ,关联权( foldrr部分),所以

False || (False || (True || (False)))

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

(((False) || False) || False) || True
-- ^ initial

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

Prelude中的foldr函数是一个高阶函数,它接受类型(a -> b -> b)的函数f并将其应用于类型[a]的列表,从而得到类型[b]的列表。 它还采用了应用于f的第一个应用的初始元素z

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

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)))

希望有助于直觉的折叠。

您有以下定义:

or_list :: [Bool] -> Bool

对。

让我们看看第二行:

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

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

or_list [0..n] = ...

这应该是这样的:

or_list (x:xs) = ...

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM