diff --git a/edges.cabal b/edges.cabal
--- a/edges.cabal
+++ b/edges.cabal
@@ -1,7 +1,7 @@
 name:
   edges
 version:
-  0.4.0.2
+  0.4.1
 category:
   Graphs
 synopsis:
@@ -46,6 +46,7 @@
     Edges.Node
     Edges.Potoki.Produce
     Edges.IO
+    Edges.Fold
   other-modules:
     Edges.Cereal.Instances
     Edges.Cereal.Get
@@ -63,7 +64,7 @@
     potoki >=2.0.2 && <2.1,
     potoki-cereal >=0.3 && <0.4,
     primitive >=0.6.4 && <0.7,
-    primitive-extras >=0.6.1 && <0.7,
+    primitive-extras >=0.6.2 && <0.7,
     profunctors >=5 && <6,
     QuickCheck >=2.8.1 && <3,
     semigroupoids >=5.2 && <6,
diff --git a/library/Edges/Fold.hs b/library/Edges/Fold.hs
new file mode 100644
--- /dev/null
+++ b/library/Edges/Fold.hs
@@ -0,0 +1,22 @@
+module Edges.Fold
+where
+
+import Edges.Prelude
+import Edges.Types
+import Edges.Node ()
+import Edges.NodeCounts ()
+import qualified PrimitiveExtras.PrimArray as PrimArray
+import qualified PrimitiveExtras.PrimMultiArray as PrimMultiArray
+
+
+edgeCounts :: Amount a -> Fold (Edge a b) (EdgeCounts a b)
+edgeCounts (Amount amountInt) =
+  dimap edgeSourceIndex EdgeCounts (PrimArray.indexCountsFold amountInt)
+  where
+    edgeSourceIndex (Edge sourceIndex _) = sourceIndex
+
+edges :: EdgeCounts a b -> Amount b -> Fold (Edge a b) (Edges a b)
+edges (EdgeCounts edgeCountsPrimArray) (Amount bAmountInt) =
+  dimap edgePair (Edges bAmountInt) (PrimMultiArray.fold edgeCountsPrimArray)
+  where
+    edgePair (Edge sourceIndex targetIndex) = (sourceIndex, targetIndex)
diff --git a/library/Edges/Types.hs b/library/Edges/Types.hs
--- a/library/Edges/Types.hs
+++ b/library/Edges/Types.hs
@@ -1,14 +1,22 @@
+{-# LANGUAGE StrictData #-}
+{-# OPTIONS_GHC -funbox-strict-fields #-}
 module Edges.Types
 where
 
 import Edges.Prelude
 
 
-data Edges source target =
-  Edges
-    {-# UNPACK #-} !Int {- Target array size -}
-    {-# UNPACK #-} !(PrimMultiArray Word32)
+data Edges source target = Edges Int {- Target array size -} (PrimMultiArray Word32)
 
 newtype Node entity = Node Int
 
 newtype NodeCounts entity = NodeCounts (PrimArray Word32)
+
+newtype EdgeCounts source target = EdgeCounts (PrimArray Word32)
+
+data Edge source target = Edge Int Word32
+
+{-|
+Total amount of unique entities of the type
+-}
+newtype Amount entity = Amount Int
