2016-12-02 60 views
2

如果我用下面的Source哈斯克尔管道过滤器不同的值

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

是否有可能一些过滤器或组合子只适用于允许不同的值被传递到下游?

那么在我的例子中,只有[1,3,2]会传递到下游?

+0

有没有什么你越了解这些价值?用某种元数据过滤该列表会容易得多。 – suffi

+2

请注意,像这样的'nub'导管不会流。由于这种或那种方式,它将使用不确定的存储器,导管必须记录它看到的例如在一个Data.Set.Set – Michael

+0

@suffi在我的情况下,类型只是一个ID列表 – tmortiboy

回答

5

像这样的东西应该做的:

#!/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] 
+3

为了更好的算法复杂性,你可以使用'Set'或'HashSet'来代替,尽管这会产生一个Ord或' Hashable'约束。 –

0
#!/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]