我需要在Haskell中定义函数,对于给定的列表列表,它将创建其最后元素的列表。例如,对于[[1,2],[3,4]]
,它应该返回[2,4]
我尝试使用模式匹配,但ite只返回最后一个列表:
lastElement :: [[a]] -> [a]
lastElement [] = error "error"
lastElement [x] = x
lastElement (x:xs) = lastElement xs
它给了我[3,4]
你走在正确的轨道上,问题是你的代码没有递归。列表上的递归函数通常是这种形式
f :: [a] -> [b]
f [] = y
f (x:xs) = y : f xs
在评估y
之后,该结果是递归调用的“:
ed”。现在尝试使您的代码变得类似。另请注意,您不需要lastElement [x]
案例,它只是递归的简单reduntant。但是,这仅对每个元素应用某些功能。您还需要一个函数f :: [a] -> a
来从一个列表中获取最后一个元素。你现在的功能就是这样,但是有一个标准的库函数。看看Hoogle:您可以按类型或描述搜索库函数
在这种情况下,我会使用列表理解,因为我认为阅读会更清楚。看看那个
Haskell是一种函数式语言,它允许您更多地考虑应用于数据的更改,而不是您需要实现的步骤。如果您了解它们,则可以使用更高阶的功能。特别是,功能map :: (a -> b) -> [a] -> [b]
。正如您可以从此类型定义中猜测的那样,map
接受一个函数,并将其应用于列表的每个元素。看起来你已经知道了last
函数,所以你可以使用它:
lastElements :: [[a]] -> [a]
lastElements = map last
看看这段代码现在多么简洁明了;无需考虑递归的作用,您只需看到它从每个列表中获取最后一个元素。
我将假设您在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