在 Haskell 中取任意类型的列表作为函数参数(使用 Replit)

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

我正在尝试在 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 内置的东西,我需要扩展才能使用它。

list haskell types syntax
1个回答
1
投票

但我想知道如何让它接受不同类型的列表,就像我有一个列表

['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]
© www.soinside.com 2019 - 2024. All rights reserved.