【问题标题】:Proper Suffixes in HaskellHaskell 中的正确后缀
【发布时间】:2019-03-12 12:44:18
【问题描述】:

我想创建一个打印列表后缀的 Haskell 函数:

该函数应执行以下操作:

> suffixes "123"
["23","3",""]
> suffixes "1"
[""]

我写了以下代码:

suffixes :: [a] -> [[a]]
suffixes []         = [] : []
suffixes f@(_:t) = f: suffixes t 

该函数将输入的字符串或字符打印为后缀,我想将其删除,因此当我输入“123”时,它应该如上所示打印。

你能帮我解决这个问题,让它不会将输入的字符串打印为后缀吗?

【问题讨论】:

  • 如果这是为了家庭作业或练习,那么@WillemVanOnsem 的答案似乎是正确的方法,但在实际代码中,您可以考虑使用来自Data.Listtails 编写suffixes = tail . tails

标签: haskell suffix


【解决方案1】:

基本上有两种方法可以做到这一点。第一种方法稍微改变了函数的工作方式:在这种情况下,基本情况返回一个空列表,递归情况产生t而不是f

suffixes :: [a] -> [[a]]
suffixes [] = []
suffixes (_:t) = t : suffixes t

这是因为t 是列表的tail,所以它是列表,但没有第一个元素。因此,我们产生了这个元素,并对尾部 t 执行递归,直到我们到达空列表。由于这个空列表已经被递归情况“产生”了,因此我们不会在基本情况下产生它。

或者我们可以只保留旧的suffixes 函数(但将其重命名为例如go),并让外部函数通过“弹出”一个元素来“预处理”列表:

suffixes :: [a] -> [[a]]
suffixes [] = []
suffixes (_:xs) = go xs
    where go [] = [] : []
          go f@(_:t) = f: go t

注意,对于一个空字符串,没有个适当的后缀,因此我们返回一个空列表。

这会产生预期的结果:

Prelude> suffixes ""
[]
Prelude> suffixes "a"
[""]
Prelude> suffixes "ab"
["b",""]
Prelude> suffixes "abc"
["bc","c",""]
Prelude> suffixes "123abc"
["23abc","3abc","abc","bc","c",""]

【讨论】:

  • \(a:t) -> t:t 不进行类型检查。
  • @MarkNeu: 但这里是a@(_:t) -> a : f t,其中f 的类型为[a] -> [[a]]。我看不到这个 lambda 表达式在哪里使用。通常\(_:_) -> t:t 不进行类型检查,因为(:) 需要一个元素,以及这些元素的列表。现在t不能是一个元素,同时也是一个这样的元素的列表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-11
  • 2018-12-13
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多