繁体   English   中英

在Haskell中进行过滤

[英]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 (***) . ((==) &&& (==)) )应用于ntup

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM