试图创建一个函数,它接受一个列表并返回与其第一个元素相同的所有元素的列表,但我的函数不起作用

时间:2016-11-03 00:02:53

标签: list haskell

特别适用于Strings。因此需要["so", "what", "and", "so", "for" "so"]并返回["so", "so", "so"]。我的问题是我的函数返回一个与输入的列表相同的列表。

以下是所有相关代码:

lookAhead :: [String] -> String
lookAhead [] = []
lookAhead (c:cs) = c

groupFirst :: [String] -> [String]
groupFirst [] = []
groupFirst (x:xs) 
    | lookAhead xs == x  = x : (groupFirst ((lookAhead xs):(tail xs)))
    | lookAhead xs /= x  = x : (groupFirst xs)
    | lookAhead xs == [] = x : []

3 个答案:

答案 0 :(得分:6)

trail作为head-element-equality-predicated filter

trail :: Eq a => [a] -> [a]
trail []       = []
trail (x : xs) = x : filter (== x) xs

trailBy使用Schwartzian transformmemoization

trailBy :: Eq b => (a -> b) -> [a] -> [a]
trailBy _ []        = []
trailBy f (x1 : xs) = let x1f = f x1
                      in  x1 : filter (\ x -> f x == x1f) xs

trail = trailBy id,其中id x = x,Haskell的身份函数。

答案 1 :(得分:2)

您的实现问题是在groupFirst内,您在列表上进行迭代并将列表尾部(类型为[String])与列表的头部进行比较({{1} })。所以每次比较都将由第二名后卫匹配,你最终会建立一个相同的名单。

您需要找到一种方法来使第一个字符串可供比较,这样您就可以在不更改函数调用的情况下迭代列表(我们需要String形式的某些内容,而不是f strList)。通过让函数调用另一个函数来解决这个问题的一种方法,将列表的头部作为参数传递:

f firstStr strList

答案 2 :(得分:1)

lookAhead函数返回第一个元素,并且该值正在groupFirst函数中递归更新。一种方法是使用列表理解:

groupFirst :: [String] -> [String] 
groupFirst [] = []
groupFirst list = [x | x <- list, head list == x]