Отдельные значения фильтра канала Haskell

Если я использую следующие Source:

 sourceList [1,3,3,1,2,3]

Можно ли применить какой-либо фильтр или комбинатор, чтобы разрешить передачу только отдельных значений вниз по течению?

Значит, в моем примере вниз по течению будет передаваться только [1,3,2]?


person tmortiboy    schedule 02.12.2016    source источник
comment
Вы больше ничего не знаете об этих ценностях? Было бы намного проще отфильтровать этот список с помощью каких-то метаданных.   -  person suffi    schedule 02.12.2016
comment
Обратите внимание, что такой канал с «утолщением» не будет передаваться. Он будет использовать неограниченную память, так как каналу так или иначе придется записывать то, что он видел, например. в Data.Set.Set   -  person Michael    schedule 03.12.2016
comment
@suffi в моем случае тип - это просто список идентификаторов   -  person tmortiboy    schedule 05.12.2016


Ответы (2)


Что-то вроде этого должно делать:

#!/usr/bin/env stack
-- stack --resolver lts-6.19 runghc --package conduit-combinators
import Conduit
import Data.Conduit.List (sourceList)

main = do
    print $ runConduitPure $ sourceList [1,3,3,1,2,3] .| myConduit [] .| sinkList

myConduit dup = do
  num <- await
  case num of
    Just x -> if x `elem` dup
              then myConduit dup
              else do
                yield x
                myConduit (x:dup)
    Nothing -> return ()

При исполнении:

sibi::casey { ~/scripts }-> ./cond.hs
[1,3,2]
person Sibi    schedule 02.12.2016
comment
Для лучшей алгоритмической сложности вы можете использовать вместо этого Set или HashSet, хотя это влечет за собой ограничение Ord или Hashable соответственно. - person Michael Snoyman; 02.12.2016

#!/usr/bin/env stack
-- stack --resolver lts-6.19 runghc --package conduit-combinators
import Conduit
import Data.Conduit.List (sourceList, mapAccum, catMaybes)
import Control.Monad (void)

main = do
    print $ runConduitPure $ sourceList [1,3,3,1,2,3] .| void (mapAccum foo []) .| catMaybes .| sinkList

foo :: Int -> [Int] -> ([Int], Maybe Int)
foo x dup | x `elem` dup = (dup, Nothing)
foo x dup = (x:dup, Just x)

При исполнении:

C:\Users\Gurkenglas\scripts>stack conduitnub.hs
[1,3,2]
person Gurkenglas    schedule 02.12.2016