非详尽模式,Haskell

时间:2018-03-24 07:11:26

标签: haskell functional-programming non-exhaustive-patterns

我正在尝试编写函数tails,它以下列方式将字符串转换为字符串列表:

tails "abc" = ["abc", "bc", "c", ""]

这是我的实施:

tails :: [Char] -> [[Char]]
tails (x:xs)
  | length (x:xs) == 0 = [""]
  | otherwise = (x:xs) : tails xs

如标题所示,此功能中有非详尽的模式。不幸的是,我不知道怎么回事。

我是Haskell的新手......任何帮助都会受到赞赏!

2 个答案:

答案 0 :(得分:3)

该模式并非详尽无遗,因为它无法接受[]。列表的格式为[]a:as,其中a是前导元素,as是尾随元素的列表。因此,仅当列表具有前导元素时,模式x:xs才匹配。修正了:

tails :: [Char] -> [[Char]]
tails xs
    | length xs == 0 = [""]
    | otherwise = let (_:xs') = xs in xs : tails xs'

然后xs接受列表,无论其形式如何。 但由于length,这是低效的,并且不适用于无限列表。

这应该是完全有效的,它可以直接模式化:

tails :: [Char] -> [[Char]]
tails [] = [""]
tails xs@(_:xs') = xs : tails xs'

答案 1 :(得分:0)

尝试这个或至少从中得到一些逻辑怎么样?它运作良好。 它有一个辅助函数将字符串转换为单独的字符列表,例如" abc"成为[" a"," b"," c"]。处理它们并不那么复杂,因此有必要在结果列表中收集不同的字符串。函数集中有两个函数,第三个函数保证用一个参数调用主函数。主要功能是在一条线上但使用警卫。

ca = [[c] | c <- "abcdef"]
f (l1,ls) | null ls = l1++[[]] | True = f ( l1 ++ [concat ls], (tail ls))
f ([],ca)
["abcdef","bcdef","cdef","def","ef","f",""]

编辑4/4/2018 我错了。 list参数不必事先制作成列表。如果不这样做,通过删除concat函数并将参数列表从元组更改为单个删除的批次或括号,函数变得更简单。

fs l1 ls = if null ls then l1++[""] else fs (l1++[ls]) (tail ls)

它的调用也不同。

fs []&#34;你好!&#34;

这本身就产生了正确的结果。

编辑/添加4/11/2018

当Haskell将输入分为头部和尾部并且tail它们已准备好使用时,重复出现(没有双关语)依赖于(x:xs)。这是一个基本的递归函数,仅对头部和尾部使用(x:xs)。我生成输入列表的所有尾部,包括null。

t [] = [""]; t (x:xs) = [x:xs] ++ t xs

而另一个将列表作为唯一参数。

t ls = [drop n ls|n<-[0..length ls - 1]]