2016-12-02 58 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]