[英]Filtering in Haskell
我想做的是获取一个元组列表,然后检查任何元组中的任何元素是否与int匹配。 如果int与元组中的任何元素匹配,则将元组添加到要返回的列表中。 一旦列表扫描了所有元组,它将返回仅与int匹配的元组列表。
filter1 :: (a -> Bool) -> [(Int, Int)] -> [(Int, Int)]
filter1 _ [] = []
filter1 p (x:xs)
| p x = x : filter1 p xs
| otherwise = filter1 p xs
这是我到目前为止所拥有的。 唯一的问题是重新递归,但出现错误,因为我正在获取元组列表并将其放回原本应该是int的位置。
如果您不介意的话,我将为您提供GHCI的一些控制台输出。
filter
的类型签名为:
Prelude> :t filter
filter :: (a -> Bool) -> [a] -> [a]
换句话说,过滤器是一个函数,它有两个参数:第一个是从任何类型的函数a
的类型Bool
,接下来就是列表a
元素。 然后,它为您提供了a
元素列表(功能为其返回True
a
元素)。
您尝试使用filter1 (5, 6) [(5, 6), (7, 8)]
示例代码几乎正确,应改为:
Prelude> filter (\x -> x == (5, 6)) [(5, 6), (7, 8)]
[(5, 6)]
我们可以使用Haskell为运算符使用的特殊语法编写该谓词。 取任何运算符,为便于说明,我们将其称为*+
; 那么(*+)
与\\xy -> x *+ y
, (a *+)
与\\y -> (a *+ y)
而(*+ b)
与\\x -> x *+ b
。 因此,我们可以简单地将上述过滤条件写为((5,6) ==)
,并且可以通过定义以下代码来使您的示例代码正常工作:
Prelude> let filter1 val = filter (val ==)
Prelude> :t filter1
filter1 :: Eq a => a -> [a] -> [a]
Prelude> filter1 (5, 6) [(5, 6), (7, 8)]
[(5,6)]
但是,这并不是您所要求的。 您要输入的是元组列表,然后检查任何元组中的任何元素是否与int匹配 。 为此,我们也需要将int:
Prelude> let tfilter n = filter (\(a, b) -> a == n || b == n)
Prelude> :t tfilter
tfilter :: Eq a => a -> [(a, a)] -> [(a, a)]
Prelude> tfilter 3 [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
[(2,3),(3,4)]
箭道:
filter :: ( a -> Bool ) -> [ (Int, Int) ] -> [ (Int, Int) ]
让我们生成过滤谓词( (Int, Int) -> Bool )
,
&&&
可用于给出( Int -> Bool, Int -> Bool )
。
例如,
( (==) &&& (==) ) 3
将产生( (==3), (==3) )
这两个部分可以通过不加循环地传递给***
。
( uncurry (***) ) ( (==3), (==3) )
将产生( (==3) *** (==3) )
产生的箭头可以用来测试我们的元组值,
( (==3) *** (==3) ) (4,3)
将产生(False, True)
然后,通过不加循环(||)
,我们得到一个函数,该函数接受一个布尔值的元组并给出其逻辑或。
( uncurry (||) ) (False, True)
将产生True
现在我们结束了:
fn tup = uncurry (||) $ ( uncurry (***) . ((==) &&& (==)) ) n tup
为了延迟无uncurry (||)
合成直到部分剩余部分( uncurry (***) . ((==) &&& (==)) )
应用于n
和tup
:
f = (uncurry (||) .) . uncurry (***) . ((==) &&& (==))
而已。
f 3 (4,5)
=> False
,
f 3 (4,3)
=> True
。
现在我们可以将f谓词与filter结合使用以获得所需的结果。
tfilter = filter . f
要么
tfilter = filter . (uncurry (||) .) . uncurry (***) . ((==) &&& (==))
tfilter 3 [ (x,y) | x<-[3..6], y<-[1..4] ]
=> [(3,1),(3,2),(3,3),(3,4),(4,3),(5,3),(6,3)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.