Haskell 实现一个带折叠功能的过滤列表
Haskell implement a filter list with fold function
filterList :: (Eq a) => a -> [(a, b)] -> [(a, b)]
>filterList " foo " [( " foo " , 1) , ( " bar " ,2) , ( " foo " ,3)]
[( " foo " ,1) ,( " 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 <b>((x, y): xs)</b> = …
但这没有多大意义,类型签名和类型推断将保证它是一个二元组列表。您在此处的模式不适用于空列表,但可能仍然需要过滤空列表。因此,您应该将其简化为:
filterList a ls = …
foldr :: (a -> b -> b) -> b -> [a] -> b
函数被赋予三个参数:
- 折叠函数
- 折叠空列表时使用的“base-case”;和
- 元素列表。
但是您不能使用 a
作为基本情况,因为该基本情况还决定了结果的类型。这里的基本情况是空列表。我们还需要将 a
传递给 filter1
函数,因此我们可以将其实现为:
filterList :: Eq a => a -> [(a, b)] -> [(a, b)]
filterList a ls = foldr (filter1 <b>a</b>) [] ls
您的 filter1
函数适用于列表,但那不是 foldr
函数的工作方式。您传递给 foldr
的函数将被赋予一个元素,以及折叠列表其余部分的 结果 。因此你的函数看起来像:
filter1 :: Eq a => a -> (a, b) -> [(a, b)] -> [(a, b)]
filter1 a (x, y) rs = …
这里a
是我们要找的已经传过去的元素,(x, y)
是我们“折进去”的二元组,rs
是结果折叠列表的其余部分。所以这是一个已经过滤的列表。
我将实施 filter1
作为练习。
filterList :: (Eq a) => a -> [(a, b)] -> [(a, b)]
>filterList " foo " [( " foo " , 1) , ( " bar " ,2) , ( " foo " ,3)]
[( " foo " ,1) ,( " 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 <b>((x, y): xs)</b> = …
但这没有多大意义,类型签名和类型推断将保证它是一个二元组列表。您在此处的模式不适用于空列表,但可能仍然需要过滤空列表。因此,您应该将其简化为:
filterList a ls = …
foldr :: (a -> b -> b) -> b -> [a] -> b
函数被赋予三个参数:
- 折叠函数
- 折叠空列表时使用的“base-case”;和
- 元素列表。
但是您不能使用 a
作为基本情况,因为该基本情况还决定了结果的类型。这里的基本情况是空列表。我们还需要将 a
传递给 filter1
函数,因此我们可以将其实现为:
filterList :: Eq a => a -> [(a, b)] -> [(a, b)]
filterList a ls = foldr (filter1 <b>a</b>) [] ls
您的 filter1
函数适用于列表,但那不是 foldr
函数的工作方式。您传递给 foldr
的函数将被赋予一个元素,以及折叠列表其余部分的 结果 。因此你的函数看起来像:
filter1 :: Eq a => a -> (a, b) -> [(a, b)] -> [(a, b)]
filter1 a (x, y) rs = …
这里a
是我们要找的已经传过去的元素,(x, y)
是我们“折进去”的二元组,rs
是结果折叠列表的其余部分。所以这是一个已经过滤的列表。
我将实施 filter1
作为练习。