我正在尝试在 Haskell 中编写一个函数,该函数将列表作为参数并返回它并删除最后一个元素 这是我的代码:
remLastElement :: [a] -> [a]
remLastElement [] = []
remLastElement (hd:rest) =
if null rest
then return []
else hd:remLastElement rest
我已经使用
[Int]
作为参数对其进行了测试,所以我知道它可以按预期工作,但我想知道如何让它获取不同类型的列表,就像我有一个列表 ['apples','oranges','pears']
或一个列表[2.4,7.32,1.46,4.5]
我做了一些搜索,在我发现的很多例子和文档中,[a] 被用来表示任何类型的列表,但 Replit 不接受它作为有效语法。我不确定它是否实际上是无效的语法,或者 Replit 是否出于某种原因而变得愚蠢。 我也偶然发现了 forall 东西,但据我了解,这不是 Haskell 内置的东西,我需要扩展才能使用它。
但我想知道如何让它接受不同类型的列表,就像我有一个列表
或一个列表['apples','oranges','pears']
.[2.4,7.32,1.46,4.5]
它已经这样做了,只要列表中的所有元素都具有相同的类型,所以
Int
s、String
s 等的列表就可以了。
你只是错了,你应该放下
return
。事实上,虽然列表是一个单子,但你在这里返回一个简单的列表,所以:
remLastElement :: [a] -> [a]
remLastElement [] = []
remLastElement (hd:rest) =
if null rest
then []
else hd:remLastElement rest
功能也可以通过模式匹配轻松简化,甚至可以通过以下方式提高效率:
remLastElement :: [a] -> [a]
remLastElement [] = []
remLastElement (x:xs) = go x xs
where go _ [] = []
go z (y:ys) = z : go y ys
这将防止将相同的缺点拆包两次。
我们可以用浮点数和字符串来测试这个:
ghci> remLastElement ["apples","oranges","pears"]
["apples","oranges"]
ghci> remLastElement [2.4,7.32,1.46,4.5]
[2.4,7.32,1.46]