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

问题描述 投票:1回答:2

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

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

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

它给了我[3,4]

list haskell pattern-matching
2个回答
6
投票

Problem

你走在正确的轨道上,问题是你的代码没有递归。列表上的递归函数通常是这种形式

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

在评估y之后,该结果是递归调用的“:ed”。现在尝试使您的代码变得类似。另请注意,您不需要lastElement [x]案例,它只是递归的简单reduntant。但是,这仅对每个元素应用某些功能。您还需要一个函数f :: [a] -> a来从一个列表中获取最后一个元素。你现在的功能就是这样,但是有一个标准的库函数。看看Hoogle:您可以按类型或描述搜索库函数

Better Alternative

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

Best Alternative

Haskell是一种函数式语言,它允许您更多地考虑应用于数据的更改,而不是您需要实现的步骤。如果您了解它们,则可以使用更高阶的功能。特别是,功能map :: (a -> b) -> [a] -> [b]。正如您可以从此类型定义中猜测的那样,map接受一个函数,并将其应用于列表的每个元素。看起来你已经知道了last函数,所以你可以使用它:

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

看看这段代码现在多么简洁明了;无需考虑递归的作用,您只需看到它从每个列表中获取最后一个元素。


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和z是列表,你想要返回[last of x, last of y, last of z],我们需要两件事:

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

2.将此函数应用于((a列表))[[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)相同的两个函数,并且映射与(2)相同的函数,则不需要这些。知道了这一点,你可以像上面已经完成的Lorenzo那样做:

lastElements :: [[a]] -> [a]
lastElements = map last
© www.soinside.com 2019 - 2024. All rights reserved.