Haskell中的正确前缀函数

Haskell中的正确前缀函数,haskell,Haskell,我想创建一个Haskell函数,用于打印列表的前缀: 该函数应执行以下操作: > prefixes "123" ["","1","12"] > prefixes "1" [""] 我编写了以下代码: prefixes :: [a] -> [[a]] prefixes [] = []:[] prefixes f = f : prefixes(init(f)) 函数将输入的字符串或字符作为前缀打印,并以相反方向打印。我想删除它,所以当我输入123时,它应该如上所述打印并以正

我想创建一个Haskell函数,用于打印列表的前缀:

该函数应执行以下操作:

> prefixes "123"
["","1","12"]
> prefixes "1"
[""]
我编写了以下代码:

prefixes :: [a] -> [[a]]
prefixes [] = []:[]
prefixes f =  f : prefixes(init(f)) 
函数将输入的字符串或字符作为前缀打印,并以相反方向打印。我想删除它,所以当我输入123时,它应该如上所述打印并以正确的方向显示

我们可以使用:

reverse (drop 1 f)
但我不知道如何在我的函数中实现它


你能帮我解决这个问题,使它能正确打印出来吗。

你的基本情况不正确,空列表没有正确的前缀。因此,很明显,在基本情况下,必须返回空列表才能使函数正确

现在考虑递归情况。首先,它应该总是以空列表开始,因为x:xs的前缀总是[[],…]。我们如何构造列表的其余部分,即x:xs的非空前缀

我们希望使用递归,那么如何从xs的正确前缀集构建x:xs的非空正确前缀集呢?看看你的例子123,23的前缀是[,2],我们想要构造的非空前缀是[1,12],所以我们只需在尾部每个前缀的头部加上“1”

所以在递归的情况下:空列表是一个适当的前缀,并且列表的头部添加到尾部的任何适当前缀

下面是一段代码,可以满足您的要求:

prefixes []     = []
prefixes (x:xs) = [] : map (x:) (prefixes xs)

基本大小写不正确,空列表没有正确的前缀。因此,很明显,在基本情况下,必须返回空列表才能使函数正确

现在考虑递归情况。首先,它应该总是以空列表开始,因为x:xs的前缀总是[[],…]。我们如何构造列表的其余部分,即x:xs的非空前缀

我们希望使用递归,那么如何从xs的正确前缀集构建x:xs的非空正确前缀集呢?看看你的例子123,23的前缀是[,2],我们想要构造的非空前缀是[1,12],所以我们只需在尾部每个前缀的头部加上“1”

所以在递归的情况下:空列表是一个适当的前缀,并且列表的头部添加到尾部的任何适当前缀

下面是一段代码,可以满足您的要求:

prefixes []     = []
prefixes (x:xs) = [] : map (x:) (prefixes xs)

看起来您想知道如何定义一个将调用原始定义的helper函数

prefixes xs = reverse (drop 1 (prefixes' xs)) where
    prefixes' [] = []:[]
    prefixes' f =  f : prefixes' (init(f)) 
你最初的定义,虽然看起来很有效,但却不太理想。另一个答案显示了如何更直观地执行此操作,而不需要辅助函数编辑:但是性能可能好,也可能不好。在这个功能中还有其他可以改进的地方:

[]:[]可以简单地写为[]] 第一滴是尾巴 圆括号通常可以用函数组合和$替换,以提高可读性。
看起来您想知道如何定义一个将调用原始定义的helper函数

prefixes xs = reverse (drop 1 (prefixes' xs)) where
    prefixes' [] = []:[]
    prefixes' f =  f : prefixes' (init(f)) 
你最初的定义,虽然看起来很有效,但却不太理想。另一个答案显示了如何更直观地执行此操作,而不需要辅助函数编辑:但是性能可能好,也可能不好。在这个功能中还有其他可以改进的地方:

[]:[]可以简单地写为[]] 第一滴是尾巴 圆括号通常可以用函数组合和$替换,以提高可读性。
以下是无点样式的解决方案:

prefixes = foldr (\el acc -> [] : map (el:) acc) [] 

以下是无点样式的解决方案:

prefixes = foldr (\el acc -> [] : map (el:) acc) [] 

不要使用反向drop 1 f,首先它应该是反向drop 1反向f,但更重要的是,它将不再适用于无限列表。123是123的前缀。@n.m:我认为这个函数的目的是产生正确的前缀。同样,如果这是为了家庭作业或你自己的理解,那就太好了。但是,在实际的代码中,你应该考虑写前缀LST= init LST或等效前缀= init。inits使用数据中的inits。如另一条评论中所述,该列表自GHC 7.8.4以来具有特别好的实现。不要使用反向下降1f,首先应该是反向下降1f,但更重要的是,它将不再适用于无限列表。123是123的前缀。@n.m:我认为这个函数的目的是产生正确的前缀。同样,如果这是为了家庭作业或你自己的理解,那就太好了。但是,在实际的代码中,你应该考虑写前缀LST= init LST或等效前缀= init。inits使用Data.List中的inits,正如另一条评论中所指出的,它有一个特别好的实现,因为GHC 7.8.4.OP想知道如何调用反向drop 1 f,它将他已经拥有的前缀列表转换为正确的前缀列表。当然,OP使用的获取前缀的方法是完全野蛮的,但真正的问题是IMHO比这更基本。OP想知道如何调用反向drop 1F,它将他已经拥有的前缀列表转换为正确的前缀列表 前缀。当然,OP使用的获取前缀的方法是完全野蛮的,但真正的问题是IMHO比这更基本。