diff --git a/library/Potoki/Core/Prelude.hs b/library/Potoki/Core/Prelude.hs
--- a/library/Potoki/Core/Prelude.hs
+++ b/library/Potoki/Core/Prelude.hs
@@ -119,6 +119,10 @@
 -------------------------
 import Control.DeepSeq as Exports
 
+-- deferred-folds
+-------------------------
+import DeferredFolds.Unfoldr as Exports (Unfoldr(..))
+
 --------------------------------------------------------------------------------
 
 import qualified Data.Text as A
diff --git a/library/Potoki/Core/Produce.hs b/library/Potoki/Core/Produce.hs
--- a/library/Potoki/Core/Produce.hs
+++ b/library/Potoki/Core/Produce.hs
@@ -16,10 +16,11 @@
   lazyByteString,
   enumInRange,
   mergeOrdering,
+  unfoldr,
 )
 where
 
-import Potoki.Core.Prelude
+import Potoki.Core.Prelude hiding (unfoldr)
 import Potoki.Core.Types
 import qualified Potoki.Core.Fetch as A
 import qualified Data.HashMap.Strict as B
@@ -303,3 +304,13 @@
                 writeIORef rightCache Nothing
                 return (Just right)
               Nothing -> fetchRight
+
+unfoldr :: Unfoldr a -> Produce a
+unfoldr (Unfoldr unfoldr) = Produce $ liftIO $ do
+  fetchRef <- newIORef (return Nothing)
+  writeIORef fetchRef $ let
+    step !a fetchNext = do
+      writeIORef fetchRef fetchNext
+      return (Just a)
+    in unfoldr step (return Nothing)
+  return $ Fetch $ join $ readIORef fetchRef
diff --git a/library/Potoki/Core/Transform.hs b/library/Potoki/Core/Transform.hs
--- a/library/Potoki/Core/Transform.hs
+++ b/library/Potoki/Core/Transform.hs
@@ -21,6 +21,7 @@
   mapInIO,
   reportProgress,
   handleProgressAndCountOnInterval,
+  uniquify,
   -- * ByteString
   builderChunks,
   extractLines,
diff --git a/library/Potoki/Core/Transform/Basic.hs b/library/Potoki/Core/Transform/Basic.hs
--- a/library/Potoki/Core/Transform/Basic.hs
+++ b/library/Potoki/Core/Transform/Basic.hs
@@ -322,3 +322,27 @@
     lastCount <- readIORef lastCountRef
     writeIORef lastCountRef count
     handle (count - lastCount) count
+
+uniquify :: (Eq a) => Transform a a
+uniquify = 
+  Transform $ \ (Fetch fetchIO) -> M.Acquire $ do
+    duplicateRef <- newIORef Nothing
+    return $ (, return ()) $ A.Fetch $ let
+      loop = do
+        dupliacte <- readIORef duplicateRef
+        fetch <- fetchIO
+        case fetch of
+          Nothing -> return Nothing
+          Just elem -> do
+            case dupliacte of
+              Nothing -> do
+                writeIORef duplicateRef fetch
+                return fetch
+              Just dupl -> do
+                if elem == dupl 
+                  then
+                    loop
+                  else do
+                    writeIORef duplicateRef (Just elem)
+                    return fetch
+      in loop
diff --git a/potoki-core.cabal b/potoki-core.cabal
--- a/potoki-core.cabal
+++ b/potoki-core.cabal
@@ -1,5 +1,5 @@
 name: potoki-core
-version: 2.3.2.1
+version: 2.3.3
 synopsis: Low-level components of "potoki"
 description:
   Provides everything required for building custom instances of
@@ -51,6 +51,7 @@
     base >=4.9 && <5,
     bytestring ==0.10.*,
     deepseq >=1.4.3 && <2,
+    deferred-folds >=0.9.7.1 && <0.10,
     directory >=1.3 && <2,
     foldl >=1.3 && <2,
     hashable >=1 && <2,
@@ -79,6 +80,7 @@
   build-depends:
     acquire >=0.2 && <0.3,
     attoparsec,
+    deferred-folds,
     foldl >=1.3.7 && <2,
     ilist >=0.3.1.0 && <0.4,
     split >=0.2.3.3 && <0.3,
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -19,6 +19,7 @@
 import qualified Data.Vector as G
 import qualified System.Random as H
 import qualified Acquire.Acquire as Ac
+import qualified DeferredFolds.Unfoldr as Unfoldr
 import Potoki
 import Transform
 
@@ -26,6 +27,10 @@
   defaultMain $
   testGroup "All tests" $
   [
+    testProperty "unfoldr" $ \ (list :: [Int]) ->
+      list ===
+      unsafePerformIO (C.produceAndConsume (E.unfoldr (Unfoldr.foldable list)) (D.list))
+    ,
     testGroup "lines extraction props" $ let
       chunksGen = listOf $ do
         byteList <- listOf (frequency [(1, pure 10), (20, choose (97, 122))])
@@ -157,6 +162,17 @@
       let prod = liftIO (return n)
       len <- run (C.produceAndConsume prod D.count)
       M.assert (len == 1)
+    ,
+    testCase "Check mergeOrdering" $ do
+      resourceVar1 <- newIORef Initial
+      resourceVar2 <- newIORef Initial
+      let prod1 = checkProduce resourceVar1 (/= Released) 100
+          prod2 = checkProduce resourceVar2 (/= Released) 50
+      res <- C.produceAndConsume (E.mergeOrdering (\a b -> a <= b) prod1 prod2) D.list  
+      fin1 <- readIORef resourceVar1
+      fin2 <- readIORef resourceVar2
+      assertEqual "" Released fin1
+      assertEqual "" Released fin2
     ]
 
 intToProduce :: Int -> E.Produce Int
diff --git a/test/Potoki.hs b/test/Potoki.hs
--- a/test/Potoki.hs
+++ b/test/Potoki.hs
@@ -157,6 +157,16 @@
       let prod = E.list list
       res <- run (C.produceAndTransformAndConsume prod (A.filter even) D.list)
       M.assert (res == filteredList)
+    ,
+    testCase "uniquify" $ do
+      let list = [1,1,2,3,4,5,5,5,6,7,8,9,10]
+      res <- C.produceAndTransformAndConsume (E.list list) (A.uniquify) D.list
+      assertEqual "" [1,2,3,4,5,6,7,8,9,10] res
+    ,
+    testProperty "uniquify unit test" $ \ (list :: [Int]) ->
+    let sortList = sort list
+        uniquifyList = nub sortList
+    in uniquifyList === unsafePerformIO (C.produceAndTransformAndConsume (E.list sortList) (A.uniquify) D.list)
   ]
 
 parsingPotoki :: TestTree
