haskell, фильтры цепочки - PullRequest
       9

haskell, фильтры цепочки

6 голосов
/ 11 ноября 2009

для записи "map f (map g xs)" в качестве одного вызова карты, которую вы можете написать

пример xs = map (f.g) xs

но как бы вы написали "filter p (filter q xs)" как один вызов фильтра? оператор точки не работает для фильтра, как для карт. угадаете, что вы будете использовать что-то еще для предикатов?

Ответы [ 8 ]

9 голосов
/ 11 ноября 2009

Если вы определили функцию both, которая выглядела бы так:

both :: (a -> Bool) -> (a -> Bool) -> a -> Bool
both f g x = f x && g x

Тогда вы могли бы написать:

example xs = filter (both p q) xs

Я не уверен, есть ли стандартная функция, которая делает это для вас ...

8 голосов
/ 11 ноября 2009
$ ghci
Prelude> :m +Control.Arrow
Prelude Control.Arrow> :t uncurry (&&) . ((0 <) &&& (< 10))
uncurry (&&) . ((0 <) &&& (< 10)) :: (Num a, Ord a) => a -> Bool
Prelude Control.Arrow> filter (uncurry (&&) . ((0 <) &&& (< 10))) [0..15]
[1,2,3,4,5,6,7,8,9]

Или объявите собственных операторов, если вы будете делать это часто.

infixr 3 &&:
p &&: q = \a -> p a && q a
infixr 2 ||:
p ||: q = \a -> p a || q a
not' = (.) not
all' = foldr (&&:) $ const True
any' = foldr (||:) $ const False

example xs = filter (p &&: q ||: not' r) xs
6 голосов
/ 11 ноября 2009

Почему не понимание списка?

example = [x | x <- xs, p x, q x]
-- for example
example = [x | x <- [1..10], (>3) x, x<5 ] -- [4]
4 голосов
/ 11 ноября 2009

Я бы определил лямбда-выражение.

module Main where

overTen :: Int -> Bool
overTen = (>10)

main :: IO ()
main = do
    print $ filter (\x -> overTen x && even x) [1..20]

выход:

$ ghci Test.hs
GHCi, version 6.10.4: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( Test.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
[12,14,16,18,20]
*Main>
4 голосов
/ 11 ноября 2009

Вызов списка функций для чего-либо - это, по сути, функция ap в Control.Monad. Тогда вы просто and результаты. Единственное небольшое уродство заключается в том, что ap требует, чтобы оба его аргумента находились в одной и той же монаде (в данном случае List), поэтому нам нужно составить его с return для работы здесь.

import Control.Monad
filterByMany funcs = filter (and . ap funcs . return)
3 голосов
/ 14 ноября 2009
import Data.Foldable
import Data.Monoid

p = (>4)
g = (<10)

main = print $ filter (getAll . foldMap (All.) [p,g]) [1..10]

выходы

[5,6,7,8,9]

только потому, что списки складываются, и вы можете комбинировать результаты предикатов с All моноидом

2 голосов
/ 17 июля 2012

Как насчет чего-то вроде:

example xs = filter (forAll [p,q,r,s,t,u,v]) xs

forAll:: [(a -> Bool)] -> a -> Bool
forAll funcs x = all (map ($ x) funcs)
1 голос
/ 11 ноября 2009

Я бы определил вспомогательную функцию - это, вероятно, можно было бы написать более декларативно, но у меня в системе не установлен GHCI для тестирования:

allPredicates :: [a -> Bool] -> a -> Bool
allPredicates []     _ = True
allPredicates (p:ps) x = p x && allPredicates ps x

тогда

filter (allPredicates [p, q]) xs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...