module Unison.Hashing.V2.Reference.Util
  ( hashComponents,
  )
where

import Data.Map qualified as Map
import Unison.ABT (Var)
import Unison.Hashing.V2.ABT qualified as ABT
import Unison.Hashing.V2.Reference (ReferenceId (..))
import Unison.Hashing.V2.Reference qualified as Reference
import Unison.Hashing.V2.Tokenizable (Hashable1)
import Unison.Prelude

hashComponents ::
  (Functor f, Hashable1 f, Foldable f, Eq v, Show v, Var v) =>
  (ReferenceId -> ABT.Term f v ()) ->
  Map v (ABT.Term f v a) ->
  Map v (ReferenceId, ABT.Term f v a)
hashComponents :: forall (f :: * -> *) v a.
(Functor f, Hashable1 f, Foldable f, Eq v, Show v, Var v) =>
(ReferenceId -> Term f v ())
-> Map v (Term f v a) -> Map v (ReferenceId, Term f v a)
hashComponents ReferenceId -> Term f v ()
embedRef Map v (Term f v a)
tms =
  [(v, (ReferenceId, Term f v a))] -> Map v (ReferenceId, Term f v a)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(v
v, (ReferenceId
r, Term f v a
e)) | ((v
v, Term f v a
e), ReferenceId
r) <- [((v, Term f v a), ReferenceId)]
cs]
  where
    cs :: [((v, Term f v a), ReferenceId)]
cs = [(Hash, [(v, Term f v a)])] -> [((v, Term f v a), ReferenceId)]
forall k. [(Hash, [k])] -> [(k, ReferenceId)]
Reference.components ([(Hash, [(v, Term f v a)])] -> [((v, Term f v a), ReferenceId)])
-> [(Hash, [(v, Term f v a)])] -> [((v, Term f v a), ReferenceId)]
forall a b. (a -> b) -> a -> b
$ (Hash -> Word64 -> Term f v ())
-> Map v (Term f v a) -> [(Hash, [(v, Term f v a)])]
forall (f :: * -> *) v a.
(Functor f, Hashable1 f, Foldable f, Eq v, Show v, Var v) =>
(Hash -> Word64 -> Term f v ())
-> Map v (Term f v a) -> [(Hash, [(v, Term f v a)])]
ABT.hashComponents Hash -> Word64 -> Term f v ()
ref Map v (Term f v a)
tms
    ref :: Hash -> Word64 -> Term f v ()
ref Hash
h Word64
i = ReferenceId -> Term f v ()
embedRef (Hash -> Word64 -> ReferenceId
ReferenceId Hash
h Word64
i)