问题描述
filterList :: (Eq a) => a -> [(a,b)] -> [(a,b)]
>filterList " foo " [( " foo ",1),( " bar ",2),( " foo ",3)]
[( " foo ",3)]
`first way with list comprehension :` filterList a ((x,y):xs) =[(b,c)|(b,c)<-((x,y):xs),a==b]
second way with recursive function:
filterList2 a []=[]
filterList2 a ((x,y):xs)|a==x = (x,y):filterList2 a xs
|otherwise = filterList2 a xs
filterList a ((x,y):xs) = foldr filter1 a ((x,y):xs)
filter1 b ((x,y):xs)|b==x = (x,y)
|otherwise = filter1 b xs
这不起作用。
非常感谢您的帮助。
解决方法
filterList
和filter1
函数都存在问题。 filterList
函数具有以下模式:
filterList a ((x,y): xs) = …
但这没有多大意义,类型签名和类型推断将保证它是2元组的列表。您的模式在这里不适用于空白列表,但是仍然有必要过滤空白列表。因此,您应该将其简化为:
filterList a ls = …
foldr :: (a -> b -> b) -> b -> [a] -> b
函数具有三个参数:
- 折叠功能
- “基本情况”,用于折叠空白列表;和
- 元素列表。
但是您不能使用a
作为基本情况,因为该基本情况还决定了结果的类型。基本情况是空列表。我们还需要将a
传递给filter1
函数,因此我们可以将其实现为:
filterList :: Eq a => a -> [(a,b)] -> [(a,b)]
filterList a ls = foldr (filter1 a) [] ls
您的filter1
函数在列表上起作用,但是foldr
函数却不是这样。您传递给foldr
的函数将被赋予一个元素,并且 result 会折叠列表的其余部分。因此,您的函数如下所示:
filter1 :: Eq a => a -> (a,b) -> [(a,b)]
filter1 a (x,y) rs = …
这里a
是我们必须通过的元素,(x,y)
是我们要“折叠”的2元组,而rs
是折叠其余列表。因此,这是一个已过滤的列表。
我将实施filter1
作为练习。