Haskell:创建列表中每个列表的最后一个元素的列表

时间:2019-03-31 14:22:35

标签: list haskell pattern-matching

我需要在Haskell的函数中定义函数 对于给定的列表列表,它将创建其最后一个元素的列表。 例如,对于[[1,2],[3,4]],它应返回[2,4]

我尝试使用模式匹配,但是ite只返回最后一个列表:

lastElement :: [[a]] -> [a]
lastElement [] = error "error"
lastElement [x] = x
lastElement (x:xs) = lastElement xs

它给了我[3,4]

2 个答案:

答案 0 :(得分:6)

问题

您步入正轨,问题在于您的代码未递归。列表上的递归函数通常采用以下形式:

f :: [a] -> [b]
f [] = y
f (x:xs) = y : f xs

y求值后,该结果将“ :编辑”到递归调用中。现在尝试使您的代码类似。还要注意,您不需要lastElement [x]情况,它只是递归的冗余。但是,这仅将某些功能应用于每个元素。您还将需要一个函数f :: [a] -> a来从一个列表中获取最后一个元素。到目前为止,您的函数可以做到这一点,但是有一个标准的库函数。看看Hoogle:您可以按类型或描述搜索库函数

更好的选择

在这种情况下,我将使用列表理解,因为我认为阅读起来会更清楚。看看吧

最佳选择

Haskell是一种功能语言,它使您可以更多地考虑需要对数据进行哪些更改,而不是需要执行哪些步骤。如果您知道它们,则可以为此使用更高阶的函数。特别是功能map :: (a -> b) -> [a] -> [b]。您可以从该类型定义中猜出,map接受一个函数,并将其应用于列表的每个元素。看来您已经知道last函数,因此可以使用它:

lastElements :: [[a]] -> [a]
lastElements = map last

看看这段代码现在有多简洁?无需考虑递归的作用,您只需看到它占用了每个列表的最后一个元素。

答案 1 :(得分:1)

我将假设您具有Haskell的初学者技能,并尝试更好地解释您做错了什么。

lastElement :: [[a]] -> [a]
lastElement [] = error "error"
lastElement [x] = x
lastElement (x:xs) = lastElement xs

在此函数中,您将收到一个元素列表并返回它的最后一个。发生这些元素也是列表。这样,应用lastElement [[1,2],[3,4]]将为您提供最后一个元素[3,4]。由于您需要输入列表[x,y,z],其中x y和z是列表,并且您想返回[last of x, last of y, last of z],因此我们需要两件事:

1。。该函数接收Int列表并返回其最后一个元素

2。。将此功能应用于((一个列表)的一个列表) [[a]]

要制作(1),我们可以像下面这样轻松地修改函数lastElement:

lastElement :: [a] -> a
lastElement [] = error "error"
lastElement [x] = x
lastElement (x:xs) = lastElement xs

现在,lastElement接收一个列表并返回其最后一个元素。

要制作(2),我们只需要创建一个映射函数,如下所示:

mapping :: ([a] -> a) -> [[a]] -> [a]
mapping _ [] = []
mapping f (x:xs) = (f x) : (mapping f xs)

通过这种方式,您可以致电mapping lastElement [[1,2],[3,4]],这会给您[2,4]

我要说的是,如果您知道最后两个与(1)相同的功能以及map与(2)相同的功能,则不需要这些。 / strong>。知道这一点,您可以像上面已经完成的Lorenzo一样进行操作:

lastElements :: [[a]] -> [a]
lastElements = map last