List 尝试创建一个函数,该函数接受一个列表并返回与第一个元素相同的所有元素的列表,但我的函数不是';行不通

List 尝试创建一个函数,该函数接受一个列表并返回与第一个元素相同的所有元素的列表,但我的函数不是';行不通,list,haskell,List,Haskell,特别是字符串。所以它需要[“So”,“what”,“and”,“So”,“for”“So”]并返回[“So”,“So”,“So”]。我的问题是,我的函数返回的列表与输入的列表相同 以下是所有相关代码: lookAhead :: [String] -> String lookAhead [] = [] lookAhead (c:cs) = c groupFirst :: [String] -> [String] groupFirst [] = [] groupFirst (x:xs)

特别是字符串。所以它需要
[“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 : []

您的实现的问题是,在
groupFirst
中,您正在对列表进行迭代,并将列表尾部(其类型为
[String]
)与列表头(
String
)进行比较。因此,每一个比较都会被第二个卫兵匹配,在那里你最终会建立一个相同的列表

您需要找到一种方法来访问第一个字符串进行比较,这样您就可以在不更改函数调用的情况下迭代列表(我们需要的是
f strList
,而不是
f firststrlist
)。解决此问题的一种方法是让函数调用另一个函数,将列表的开头作为参数传递:

lookAhead :: [String] -> [String]
lookAhead [] = []
lookAhead (x:xs) = x : check x xs

check :: String -> [String] -> [String]
check str = foldr (\x acc -> if x == str then x:acc else acc) []

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

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

groupFirst list=[x | x
trail
作为预测的头元素等式
过滤器

trail :: Eq a => [a] -> [a]
trail []       = []
trail (x : xs) = x : filter (== x) xs
trailBy
使用和:


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

调试的一种方法是仔细考虑输入时每一步发生的情况。您可以从
[“so”,“what”]
。如果您仍然有问题,那么您应该将解决方案分解为更小的部分。如果
x
是每个递归步骤列表的第一个元素,您希望将其与什么进行比较?在这个比较中,您需要处理多少种不同的情况?您希望何时将
x
包含在结果列表中?OP已确定在列表参数上使用模式匹配而不是
head
tail
,这是正确的;不要改变这一点。
lookAhead
在给定空列表时崩溃。(其他两个答案幸运地逃脱了这种命运,因为当列表为空时,它们的布尔测试从未实际应用)。即使它们不会在此处造成崩溃,
head
tail
是邪恶的。避免它们。通过模式匹配处理这两种情况,然后在给出空列表时决定要做什么。(这也适用于其他答案。)即使它们不会在这里造成崩溃,
head
tail
是邪恶的。避免它们。通过模式匹配处理这两种情况,然后在给出空列表时决定要做什么。(这也适用于其他答案。)
trailBy :: Eq b => (a -> b) -> [a] -> [a]
trailBy _ []        = []
trailBy f (x1 : xs) = let x1f = f x1
                      in  x1 : filter (\ x -> f x == x1f) xs