[英]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
,关联权( foldr
的r
部分),所以
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.