[英]Haskell Functions (map,foldr, foldl)
I am struggling to think of a way to utilize these functions for this beginner level coding class that I am taking to learn functional programming in Haskell. The functions I have to write are shown below, asum
is supposed to turn a list of integers [a1,a2,..,an]
into the alternating sum a1-a2+a3-a4+.…
and I am not sure how to approach it with these functions.我正在努力想办法将这些函数用于这个初学者级别的编码 class,我将在 Haskell 中学习函数式编程。我必须编写的函数如下所示, asum
应该转换整数列表[a1,a2,..,an]
转换为交替和a1-a2+a3-a4+.…
我不确定如何使用这些函数来处理它。 The xor
function is supposed to that computes the XOR of a list of Booleans. xor
function 应该计算布尔值列表的 XOR。 I need some help to understand how to use these functions and it would greatly appreciated.我需要一些帮助来了解如何使用这些功能,我将不胜感激。 I am also new to Haskell so any explanations would help.我也是 Haskell 的新手,所以任何解释都会有所帮助。 Thanks I have to use map foldr foldl
.谢谢我必须使用map foldr foldl
。
asum :: (Num a) => [a] -> a
xor :: [Bool] -> Bool
I would say start by running the following, one by one, in GHCi
:我会说首先在GHCi
中逐一运行以下命令:
:t foldr
:info foldr
:doc foldr
:t foldl
:info foldl
:doc foldl
:t map
:info map
:doc map
Or better, open hoogle.haskell.org and search each of the above mentioned functions and click on the first link.或者更好,打开hoogle.haskell.org并搜索上述每个功能,然后单击第一个链接。
But I agree that Haskell documentation are difficult to read, especially for beginners.但我同意 Haskell 文档很难阅读,尤其是对于初学者。 I'm a beginner and I have a lot of difficulty reading and understanding them.我是初学者,阅读和理解它们有很多困难。
Here's a function that uses map
and foldr
to show how foldr
works:这是一个 function,它使用map
和foldr
来展示foldr
的工作原理:
printFoldr xs = foldr (\x acc -> "(" ++ x ++ " + " ++ acc ++ " )") "0" $ map show xs
Now running watch this:现在运行看这个:
printFoldr [1..5]
-- outputs the following:
"(1 + (2 + (3 + (4 + (5 + 0 ) ) ) ) )"
This shows us how foldr
is evaluated.这向我们展示了如何评估foldr
。 Before going into how foldr
is evaluated, let's look briefly at map
.在讨论如何评估foldr
之前,让我们简要地看一下map
。
map show [1..5]
-- outputs the following:
["1","2","3","4","5"]
This means that map
takes 2 arguments. A list and a function that is applied to each element of the list.这意味着map
需要 2 个 arguments. 列表和一个应用于列表每个元素的 function。 The result is a new list with the function applied to each element.结果是一个新列表,每个元素都应用了 function。 Thus, applying show
to each number outputs their string representation.因此,将show
应用于每个数字会输出它们的字符串表示形式。
Back to foldr
.返回foldr
。 foldr
takes 3 arguments: foldr
需要 3 arguments:
a -> b -> b
a function 类型a -> b -> b
b
类型b
的初始值[a]
[a]
类型的列表foldr
takes each and every value of the provided list and applies this function to it. foldr
获取所提供列表的每个值并将此 function 应用于它。 What is special is that map retains the output of the function over each iteration and passes it to the function as its second argument on the next run.特别之处在于 map 在每次迭代中保留 function 的 output,并在下一次运行时将其作为第二个参数传递给 function。 Therefore it is convenient to write the function that is passed foldr
as follows: (\el acc -> do something)
.因此,将传递给foldr
的 function 编写如下很方便: (\el acc -> do something)
。 Now on the next iteration of foldr
, acc
will hold the value of the previous run and el
will be the current element from the list.现在在foldr
的下一次迭代中, acc
将保留上一次运行的值,而el
将是列表中的当前元素。 BTW, acc
stands for accumulator and el
for element.顺便说一句, acc
代表累加器, el
代表元素。 This enables us to reduce elements of the provided list to something completely new.这使我们能够将提供的列表的元素减少为全新的东西。
As you can see in printFoldr
, the initial value is just an empty string but it gradually adds the lists elements to it showing how it would have reduced the elements of the list to their sum.正如您在printFoldr
中看到的,初始值只是一个空字符串,但它逐渐向其中添加列表元素,显示它将如何将列表元素减少到它们的总和。
Here's an idea:这是一个想法:
a1-a2+a3-a4+...
=
a1-(a2-(a3-(a4-(...(an-0)...))))
This fits pretty well to the foldr
pattern of recursion,这非常适合递归的foldr
模式,
foldr f z [a1,a2,a3,a4,...,an]
=
a1`f`(a2`f`(a3`f`(a4`f`(...(an`f`z)...))))
So it can be coded by setting f =...
and z =...
and calling所以它可以通过设置f =...
和z =...
并调用来编码
asum :: (Num a) => [a] -> a
asum xs = foldr f z xs
where
f = (...)
z = (...)
You will need to complete this definition.您将需要完成此定义。
For the XOR
of a list of Booleans, assuming it is to be True
if one and only one of them is True
, and False
otherwise, we can imagine this sequence of transformations:对于布尔值列表的XOR
,假设只有其中一个为True
则为True
,否则为False
,我们可以想象以下转换序列:
[ True, False, False, True, True, False, ...]
==>
[ t, f, f, t, t, f, ...]
where t
and f
are some specially chosen numbers.其中t
和f
是一些特别选择的数字。 And then we can find the sum of this second list (not alternating sum, just a sum of a list of numbers) and check whether it is equal to... some (other?) special number, let's call it n1
:然后我们可以找到第二个列表的总和(不是交替总和,只是数字列表的总和)并检查它是否等于......一些(其他?)特殊数字,我们称之为n1
:
xor :: [Bool] -> Bool
xor bools = (aNumber ... n1)
where
list1 = bools
list2 = fun1 transform list1
transform False = f
transform True = t
f = ...
t = ...
aNumber = sum list2
n1 = ...
fun1 = ...
sum listOfNums = ...
fun1
is the function which transforms each element of its argument list according to the given function, called transform
above. fun1
是 function,它根据给定的 function 转换其参数列表的每个元素,在上面称为transform
。 It is one of the two functions left from the three you were given, considering we've already been using foldr
.考虑到我们已经在使用foldr
,它是您获得的三个功能中剩下的两个功能之一。
sum
is to be implemented by using the last function that's left. sum
将通过使用剩下的最后一个 function 来实现。
FYI,供参考,
map foo [a1,a2,a3,...,an]
=
[foo a1, foo a2, foo a3, ..., foo an]
and和
foldl f z [a1,a2,a3,...,an]
=
((((z`f`a1)`f`a2)`f`a3)...)`f`an
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.