module U.Codebase.Reference
  ( Reference,
    RReference,
    TermReference,
    TermRReference,
    TermReferenceId,
    TypeReference,
    TypeRReference,
    TypeReferenceId,
    Reference' (..),
    TermReference',
    TypeReference',
    ReferenceType (..),
    pattern Derived,
    Id,
    Id' (..),
    Pos,
    _ReferenceDerived,
    _RReferenceReference,
    t_,
    h_,
    idH,
    idPos,
    idToHash,
    idToShortHash,
    isBuiltin,
    toShortHash,
    toId,
    unsafeId,
    component,
  )
where

import Control.Lens (Lens, Lens', Prism, Prism', Traversal, lens, preview, prism)
import Data.Bifoldable (Bifoldable (..))
import Data.Bitraversable (Bitraversable (..))
import Data.Text qualified as Text
import Unison.Hash (Hash)
import Unison.Hash qualified as H
import Unison.Hash qualified as Hash
import Unison.Prelude
import Unison.ShortHash (ShortHash)
import Unison.ShortHash qualified as SH

-- | This is the canonical representation of Reference
type Reference = Reference' Text Hash

-- | A possibly-self (R = "recursive") reference.
type RReference = Reference' Text (Maybe Hash)

-- | A term reference.
type TermReference = Reference

-- | A possibly-self term reference.
type TermRReference = RReference

-- | A type declaration reference.
type TypeReference = Reference

-- | A possibly-self type declaration reference.
type TypeRReference = RReference

type Id = Id' Hash

-- | A term reference id.
type TermReferenceId = Id

-- | A type declaration reference id.
type TypeReferenceId = Id

data ReferenceType = RtTerm | RtType deriving (ReferenceType -> ReferenceType -> Bool
(ReferenceType -> ReferenceType -> Bool)
-> (ReferenceType -> ReferenceType -> Bool) -> Eq ReferenceType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ReferenceType -> ReferenceType -> Bool
== :: ReferenceType -> ReferenceType -> Bool
$c/= :: ReferenceType -> ReferenceType -> Bool
/= :: ReferenceType -> ReferenceType -> Bool
Eq, Eq ReferenceType
Eq ReferenceType =>
(ReferenceType -> ReferenceType -> Ordering)
-> (ReferenceType -> ReferenceType -> Bool)
-> (ReferenceType -> ReferenceType -> Bool)
-> (ReferenceType -> ReferenceType -> Bool)
-> (ReferenceType -> ReferenceType -> Bool)
-> (ReferenceType -> ReferenceType -> ReferenceType)
-> (ReferenceType -> ReferenceType -> ReferenceType)
-> Ord ReferenceType
ReferenceType -> ReferenceType -> Bool
ReferenceType -> ReferenceType -> Ordering
ReferenceType -> ReferenceType -> ReferenceType
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ReferenceType -> ReferenceType -> Ordering
compare :: ReferenceType -> ReferenceType -> Ordering
$c< :: ReferenceType -> ReferenceType -> Bool
< :: ReferenceType -> ReferenceType -> Bool
$c<= :: ReferenceType -> ReferenceType -> Bool
<= :: ReferenceType -> ReferenceType -> Bool
$c> :: ReferenceType -> ReferenceType -> Bool
> :: ReferenceType -> ReferenceType -> Bool
$c>= :: ReferenceType -> ReferenceType -> Bool
>= :: ReferenceType -> ReferenceType -> Bool
$cmax :: ReferenceType -> ReferenceType -> ReferenceType
max :: ReferenceType -> ReferenceType -> ReferenceType
$cmin :: ReferenceType -> ReferenceType -> ReferenceType
min :: ReferenceType -> ReferenceType -> ReferenceType
Ord, Int -> ReferenceType -> ShowS
[ReferenceType] -> ShowS
ReferenceType -> [Char]
(Int -> ReferenceType -> ShowS)
-> (ReferenceType -> [Char])
-> ([ReferenceType] -> ShowS)
-> Show ReferenceType
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ReferenceType -> ShowS
showsPrec :: Int -> ReferenceType -> ShowS
$cshow :: ReferenceType -> [Char]
show :: ReferenceType -> [Char]
$cshowList :: [ReferenceType] -> ShowS
showList :: [ReferenceType] -> ShowS
Show)

-- | Either a builtin or a user defined (hashed) top-level declaration. Used for both terms and types.
data Reference' t h
  = ReferenceBuiltin t
  | ReferenceDerived (Id' h)
  deriving stock (Reference' t h -> Reference' t h -> Bool
(Reference' t h -> Reference' t h -> Bool)
-> (Reference' t h -> Reference' t h -> Bool)
-> Eq (Reference' t h)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall t h.
(Eq t, Eq h) =>
Reference' t h -> Reference' t h -> Bool
$c== :: forall t h.
(Eq t, Eq h) =>
Reference' t h -> Reference' t h -> Bool
== :: Reference' t h -> Reference' t h -> Bool
$c/= :: forall t h.
(Eq t, Eq h) =>
Reference' t h -> Reference' t h -> Bool
/= :: Reference' t h -> Reference' t h -> Bool
Eq, (forall x. Reference' t h -> Rep (Reference' t h) x)
-> (forall x. Rep (Reference' t h) x -> Reference' t h)
-> Generic (Reference' t h)
forall x. Rep (Reference' t h) x -> Reference' t h
forall x. Reference' t h -> Rep (Reference' t h) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall t h x. Rep (Reference' t h) x -> Reference' t h
forall t h x. Reference' t h -> Rep (Reference' t h) x
$cfrom :: forall t h x. Reference' t h -> Rep (Reference' t h) x
from :: forall x. Reference' t h -> Rep (Reference' t h) x
$cto :: forall t h x. Rep (Reference' t h) x -> Reference' t h
to :: forall x. Rep (Reference' t h) x -> Reference' t h
Generic, (forall a b. (a -> b) -> Reference' t a -> Reference' t b)
-> (forall a b. a -> Reference' t b -> Reference' t a)
-> Functor (Reference' t)
forall a b. a -> Reference' t b -> Reference' t a
forall a b. (a -> b) -> Reference' t a -> Reference' t b
forall t a b. a -> Reference' t b -> Reference' t a
forall t a b. (a -> b) -> Reference' t a -> Reference' t b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall t a b. (a -> b) -> Reference' t a -> Reference' t b
fmap :: forall a b. (a -> b) -> Reference' t a -> Reference' t b
$c<$ :: forall t a b. a -> Reference' t b -> Reference' t a
<$ :: forall a b. a -> Reference' t b -> Reference' t a
Functor, Eq (Reference' t h)
Eq (Reference' t h) =>
(Reference' t h -> Reference' t h -> Ordering)
-> (Reference' t h -> Reference' t h -> Bool)
-> (Reference' t h -> Reference' t h -> Bool)
-> (Reference' t h -> Reference' t h -> Bool)
-> (Reference' t h -> Reference' t h -> Bool)
-> (Reference' t h -> Reference' t h -> Reference' t h)
-> (Reference' t h -> Reference' t h -> Reference' t h)
-> Ord (Reference' t h)
Reference' t h -> Reference' t h -> Bool
Reference' t h -> Reference' t h -> Ordering
Reference' t h -> Reference' t h -> Reference' t h
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall t h. (Ord t, Ord h) => Eq (Reference' t h)
forall t h.
(Ord t, Ord h) =>
Reference' t h -> Reference' t h -> Bool
forall t h.
(Ord t, Ord h) =>
Reference' t h -> Reference' t h -> Ordering
forall t h.
(Ord t, Ord h) =>
Reference' t h -> Reference' t h -> Reference' t h
$ccompare :: forall t h.
(Ord t, Ord h) =>
Reference' t h -> Reference' t h -> Ordering
compare :: Reference' t h -> Reference' t h -> Ordering
$c< :: forall t h.
(Ord t, Ord h) =>
Reference' t h -> Reference' t h -> Bool
< :: Reference' t h -> Reference' t h -> Bool
$c<= :: forall t h.
(Ord t, Ord h) =>
Reference' t h -> Reference' t h -> Bool
<= :: Reference' t h -> Reference' t h -> Bool
$c> :: forall t h.
(Ord t, Ord h) =>
Reference' t h -> Reference' t h -> Bool
> :: Reference' t h -> Reference' t h -> Bool
$c>= :: forall t h.
(Ord t, Ord h) =>
Reference' t h -> Reference' t h -> Bool
>= :: Reference' t h -> Reference' t h -> Bool
$cmax :: forall t h.
(Ord t, Ord h) =>
Reference' t h -> Reference' t h -> Reference' t h
max :: Reference' t h -> Reference' t h -> Reference' t h
$cmin :: forall t h.
(Ord t, Ord h) =>
Reference' t h -> Reference' t h -> Reference' t h
min :: Reference' t h -> Reference' t h -> Reference' t h
Ord, Int -> Reference' t h -> ShowS
[Reference' t h] -> ShowS
Reference' t h -> [Char]
(Int -> Reference' t h -> ShowS)
-> (Reference' t h -> [Char])
-> ([Reference' t h] -> ShowS)
-> Show (Reference' t h)
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
forall t h. (Show t, Show h) => Int -> Reference' t h -> ShowS
forall t h. (Show t, Show h) => [Reference' t h] -> ShowS
forall t h. (Show t, Show h) => Reference' t h -> [Char]
$cshowsPrec :: forall t h. (Show t, Show h) => Int -> Reference' t h -> ShowS
showsPrec :: Int -> Reference' t h -> ShowS
$cshow :: forall t h. (Show t, Show h) => Reference' t h -> [Char]
show :: Reference' t h -> [Char]
$cshowList :: forall t h. (Show t, Show h) => [Reference' t h] -> ShowS
showList :: [Reference' t h] -> ShowS
Show)

-- | A type declaration reference.
type TermReference' t h = Reference' t h

-- | A term declaration reference.
type TypeReference' t h = Reference' t h

_RReferenceReference :: Prism' (Reference' t (Maybe h)) (Reference' t h)
_RReferenceReference :: forall t h (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Reference' t h) (f (Reference' t h))
-> p (Reference' t (Maybe h)) (f (Reference' t (Maybe h)))
_RReferenceReference = (Reference' t h -> Reference' t (Maybe h))
-> (Reference' t (Maybe h)
    -> Either (Reference' t (Maybe h)) (Reference' t h))
-> Prism
     (Reference' t (Maybe h))
     (Reference' t (Maybe h))
     (Reference' t h)
     (Reference' t h)
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism Reference' t h -> Reference' t (Maybe h)
forall {t} {a}. Reference' t a -> Reference' t (Maybe a)
embed Reference' t (Maybe h)
-> Either (Reference' t (Maybe h)) (Reference' t h)
forall {t} {h} {t}.
Reference' t (Maybe h)
-> Either (Reference' t (Maybe h)) (Reference' t h)
project
  where
    embed :: Reference' t a -> Reference' t (Maybe a)
embed = \case
      ReferenceBuiltin t
x -> t -> Reference' t (Maybe a)
forall t h. t -> Reference' t h
ReferenceBuiltin t
x
      ReferenceDerived (Id a
h Pos
p) -> Id' (Maybe a) -> Reference' t (Maybe a)
forall t h. Id' h -> Reference' t h
ReferenceDerived (Maybe a -> Pos -> Id' (Maybe a)
forall h. h -> Pos -> Id' h
Id (a -> Maybe a
forall a. a -> Maybe a
Just a
h) Pos
p)

    project :: Reference' t (Maybe h)
-> Either (Reference' t (Maybe h)) (Reference' t h)
project = \case
      ReferenceBuiltin t
x -> Reference' t h -> Either (Reference' t (Maybe h)) (Reference' t h)
forall a b. b -> Either a b
Right (t -> Reference' t h
forall t h. t -> Reference' t h
ReferenceBuiltin t
x)
      ReferenceDerived (Id Maybe h
mh Pos
p) -> case Maybe h
mh of
        Maybe h
Nothing -> Reference' t (Maybe h)
-> Either (Reference' t (Maybe h)) (Reference' t h)
forall a b. a -> Either a b
Left (Id' (Maybe h) -> Reference' t (Maybe h)
forall t h. Id' h -> Reference' t h
ReferenceDerived (Maybe h -> Pos -> Id' (Maybe h)
forall h. h -> Pos -> Id' h
Id Maybe h
mh Pos
p))
        Just h
h -> Reference' t h -> Either (Reference' t (Maybe h)) (Reference' t h)
forall a b. b -> Either a b
Right (Id' h -> Reference' t h
forall t h. Id' h -> Reference' t h
ReferenceDerived (h -> Pos -> Id' h
forall h. h -> Pos -> Id' h
Id h
h Pos
p))

_ReferenceDerived :: Prism (Reference' t h) (Reference' t h') (Id' h) (Id' h')
_ReferenceDerived :: forall t h h' (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Id' h) (f (Id' h')) -> p (Reference' t h) (f (Reference' t h'))
_ReferenceDerived = (Id' h' -> Reference' t h')
-> (Reference' t h -> Either (Reference' t h') (Id' h))
-> Prism (Reference' t h) (Reference' t h') (Id' h) (Id' h')
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism Id' h' -> Reference' t h'
forall {h} {t}. Id' h -> Reference' t h
embed Reference' t h -> Either (Reference' t h') (Id' h)
forall {t} {h} {h}.
Reference' t h -> Either (Reference' t h) (Id' h)
project
  where
    embed :: Id' h -> Reference' t h
embed (Id h
h Pos
pos) = Id' h -> Reference' t h
forall t h. Id' h -> Reference' t h
ReferenceDerived (h -> Pos -> Id' h
forall h. h -> Pos -> Id' h
Id h
h Pos
pos)
    project :: Reference' t h -> Either (Reference' t h) (Id' h)
project (ReferenceDerived Id' h
id') = Id' h -> Either (Reference' t h) (Id' h)
forall a b. b -> Either a b
Right Id' h
id'
    project (ReferenceBuiltin t
t) = Reference' t h -> Either (Reference' t h) (Id' h)
forall a b. a -> Either a b
Left (t -> Reference' t h
forall t h. t -> Reference' t h
ReferenceBuiltin t
t)

pattern Derived :: h -> Pos -> Reference' t h
pattern $mDerived :: forall {r} {h} {t}.
Reference' t h -> (h -> Pos -> r) -> ((# #) -> r) -> r
$bDerived :: forall h t. h -> Pos -> Reference' t h
Derived h i = ReferenceDerived (Id h i)

{-# COMPLETE ReferenceBuiltin, Derived #-}

type Pos = Word64

-- | @Pos@ is a position into a cycle, as cycles are hashed together.
data Id' h = Id h Pos
  deriving stock (Id' h -> Id' h -> Bool
(Id' h -> Id' h -> Bool) -> (Id' h -> Id' h -> Bool) -> Eq (Id' h)
forall h. Eq h => Id' h -> Id' h -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall h. Eq h => Id' h -> Id' h -> Bool
== :: Id' h -> Id' h -> Bool
$c/= :: forall h. Eq h => Id' h -> Id' h -> Bool
/= :: Id' h -> Id' h -> Bool
Eq, Eq (Id' h)
Eq (Id' h) =>
(Id' h -> Id' h -> Ordering)
-> (Id' h -> Id' h -> Bool)
-> (Id' h -> Id' h -> Bool)
-> (Id' h -> Id' h -> Bool)
-> (Id' h -> Id' h -> Bool)
-> (Id' h -> Id' h -> Id' h)
-> (Id' h -> Id' h -> Id' h)
-> Ord (Id' h)
Id' h -> Id' h -> Bool
Id' h -> Id' h -> Ordering
Id' h -> Id' h -> Id' h
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall h. Ord h => Eq (Id' h)
forall h. Ord h => Id' h -> Id' h -> Bool
forall h. Ord h => Id' h -> Id' h -> Ordering
forall h. Ord h => Id' h -> Id' h -> Id' h
$ccompare :: forall h. Ord h => Id' h -> Id' h -> Ordering
compare :: Id' h -> Id' h -> Ordering
$c< :: forall h. Ord h => Id' h -> Id' h -> Bool
< :: Id' h -> Id' h -> Bool
$c<= :: forall h. Ord h => Id' h -> Id' h -> Bool
<= :: Id' h -> Id' h -> Bool
$c> :: forall h. Ord h => Id' h -> Id' h -> Bool
> :: Id' h -> Id' h -> Bool
$c>= :: forall h. Ord h => Id' h -> Id' h -> Bool
>= :: Id' h -> Id' h -> Bool
$cmax :: forall h. Ord h => Id' h -> Id' h -> Id' h
max :: Id' h -> Id' h -> Id' h
$cmin :: forall h. Ord h => Id' h -> Id' h -> Id' h
min :: Id' h -> Id' h -> Id' h
Ord, Int -> Id' h -> ShowS
[Id' h] -> ShowS
Id' h -> [Char]
(Int -> Id' h -> ShowS)
-> (Id' h -> [Char]) -> ([Id' h] -> ShowS) -> Show (Id' h)
forall h. Show h => Int -> Id' h -> ShowS
forall h. Show h => [Id' h] -> ShowS
forall h. Show h => Id' h -> [Char]
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall h. Show h => Int -> Id' h -> ShowS
showsPrec :: Int -> Id' h -> ShowS
$cshow :: forall h. Show h => Id' h -> [Char]
show :: Id' h -> [Char]
$cshowList :: forall h. Show h => [Id' h] -> ShowS
showList :: [Id' h] -> ShowS
Show, (forall a b. (a -> b) -> Id' a -> Id' b)
-> (forall a b. a -> Id' b -> Id' a) -> Functor Id'
forall a b. a -> Id' b -> Id' a
forall a b. (a -> b) -> Id' a -> Id' b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Id' a -> Id' b
fmap :: forall a b. (a -> b) -> Id' a -> Id' b
$c<$ :: forall a b. a -> Id' b -> Id' a
<$ :: forall a b. a -> Id' b -> Id' a
Functor, (forall m. Monoid m => Id' m -> m)
-> (forall m a. Monoid m => (a -> m) -> Id' a -> m)
-> (forall m a. Monoid m => (a -> m) -> Id' a -> m)
-> (forall a b. (a -> b -> b) -> b -> Id' a -> b)
-> (forall a b. (a -> b -> b) -> b -> Id' a -> b)
-> (forall b a. (b -> a -> b) -> b -> Id' a -> b)
-> (forall b a. (b -> a -> b) -> b -> Id' a -> b)
-> (forall a. (a -> a -> a) -> Id' a -> a)
-> (forall a. (a -> a -> a) -> Id' a -> a)
-> (forall a. Id' a -> [a])
-> (forall a. Id' a -> Bool)
-> (forall a. Id' a -> Int)
-> (forall a. Eq a => a -> Id' a -> Bool)
-> (forall a. Ord a => Id' a -> a)
-> (forall a. Ord a => Id' a -> a)
-> (forall a. Num a => Id' a -> a)
-> (forall a. Num a => Id' a -> a)
-> Foldable Id'
forall a. Eq a => a -> Id' a -> Bool
forall a. Num a => Id' a -> a
forall a. Ord a => Id' a -> a
forall m. Monoid m => Id' m -> m
forall a. Id' a -> Bool
forall a. Id' a -> Int
forall a. Id' a -> [a]
forall a. (a -> a -> a) -> Id' a -> a
forall m a. Monoid m => (a -> m) -> Id' a -> m
forall b a. (b -> a -> b) -> b -> Id' a -> b
forall a b. (a -> b -> b) -> b -> Id' a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => Id' m -> m
fold :: forall m. Monoid m => Id' m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Id' a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Id' a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Id' a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Id' a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> Id' a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Id' a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Id' a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Id' a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Id' a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Id' a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Id' a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Id' a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> Id' a -> a
foldr1 :: forall a. (a -> a -> a) -> Id' a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Id' a -> a
foldl1 :: forall a. (a -> a -> a) -> Id' a -> a
$ctoList :: forall a. Id' a -> [a]
toList :: forall a. Id' a -> [a]
$cnull :: forall a. Id' a -> Bool
null :: forall a. Id' a -> Bool
$clength :: forall a. Id' a -> Int
length :: forall a. Id' a -> Int
$celem :: forall a. Eq a => a -> Id' a -> Bool
elem :: forall a. Eq a => a -> Id' a -> Bool
$cmaximum :: forall a. Ord a => Id' a -> a
maximum :: forall a. Ord a => Id' a -> a
$cminimum :: forall a. Ord a => Id' a -> a
minimum :: forall a. Ord a => Id' a -> a
$csum :: forall a. Num a => Id' a -> a
sum :: forall a. Num a => Id' a -> a
$cproduct :: forall a. Num a => Id' a -> a
product :: forall a. Num a => Id' a -> a
Foldable, Functor Id'
Foldable Id'
(Functor Id', Foldable Id') =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Id' a -> f (Id' b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Id' (f a) -> f (Id' a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Id' a -> m (Id' b))
-> (forall (m :: * -> *) a. Monad m => Id' (m a) -> m (Id' a))
-> Traversable Id'
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Id' (m a) -> m (Id' a)
forall (f :: * -> *) a. Applicative f => Id' (f a) -> f (Id' a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Id' a -> m (Id' b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Id' a -> f (Id' b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Id' a -> f (Id' b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Id' a -> f (Id' b)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Id' (f a) -> f (Id' a)
sequenceA :: forall (f :: * -> *) a. Applicative f => Id' (f a) -> f (Id' a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Id' a -> m (Id' b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Id' a -> m (Id' b)
$csequence :: forall (m :: * -> *) a. Monad m => Id' (m a) -> m (Id' a)
sequence :: forall (m :: * -> *) a. Monad m => Id' (m a) -> m (Id' a)
Traversable)

t_ :: Prism (Reference' t h) (Reference' t' h) t t'
t_ :: forall t h t' (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p t (f t') -> p (Reference' t h) (f (Reference' t' h))
t_ = (t' -> Reference' t' h)
-> (Reference' t h -> Either (Reference' t' h) t)
-> Prism (Reference' t h) (Reference' t' h) t t'
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism t' -> Reference' t' h
forall t h. t -> Reference' t h
ReferenceBuiltin \case
  ReferenceBuiltin t
t -> t -> Either (Reference' t' h) t
forall a b. b -> Either a b
Right t
t
  ReferenceDerived Id' h
id -> Reference' t' h -> Either (Reference' t' h) t
forall a b. a -> Either a b
Left (Id' h -> Reference' t' h
forall t h. Id' h -> Reference' t h
ReferenceDerived Id' h
id)

h_ :: Traversal (Reference' t h) (Reference' t h') h h'
h_ :: forall t h h' (f :: * -> *).
Applicative f =>
(h -> f h') -> Reference' t h -> f (Reference' t h')
h_ h -> f h'
f = \case
  ReferenceBuiltin t
t -> Reference' t h' -> f (Reference' t h')
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (t -> Reference' t h'
forall t h. t -> Reference' t h
ReferenceBuiltin t
t)
  Derived h
h Pos
i -> h' -> Pos -> Reference' t h'
forall h t. h -> Pos -> Reference' t h
Derived (h' -> Pos -> Reference' t h')
-> f h' -> f (Pos -> Reference' t h')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> h -> f h'
f h
h f (Pos -> Reference' t h') -> f Pos -> f (Reference' t h')
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Pos -> f Pos
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Pos
i

idPos :: Lens' (Id' h) Pos
idPos :: forall h (f :: * -> *).
Functor f =>
(Pos -> f Pos) -> Id' h -> f (Id' h)
idPos = (Id' h -> Pos)
-> (Id' h -> Pos -> Id' h) -> Lens (Id' h) (Id' h) Pos Pos
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens (\(Id h
_h Pos
w) -> Pos
w) (\(Id h
h Pos
_w) Pos
w -> h -> Pos -> Id' h
forall h. h -> Pos -> Id' h
Id h
h Pos
w)

idH :: Lens (Id' h) (Id' h') h h'
idH :: forall h h' (f :: * -> *).
Functor f =>
(h -> f h') -> Id' h -> f (Id' h')
idH = (Id' h -> h)
-> (Id' h -> h' -> Id' h') -> Lens (Id' h) (Id' h') h h'
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens (\(Id h
h Pos
_w) -> h
h) (\(Id h
_h Pos
w) h'
h -> h' -> Pos -> Id' h'
forall h. h -> Pos -> Id' h
Id h'
h Pos
w)

idToHash :: Id -> Hash
idToHash :: Id -> Hash
idToHash (Id Hash
h Pos
_) = Hash
h

idToShortHash :: Id -> ShortHash
idToShortHash :: Id -> ShortHash
idToShortHash = Reference' Text Hash -> ShortHash
toShortHash (Reference' Text Hash -> ShortHash)
-> (Id -> Reference' Text Hash) -> Id -> ShortHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> Reference' Text Hash
forall t h. Id' h -> Reference' t h
ReferenceDerived

isBuiltin :: Reference -> Bool
isBuiltin :: Reference' Text Hash -> Bool
isBuiltin (ReferenceBuiltin Text
_) = Bool
True
isBuiltin Reference' Text Hash
_ = Bool
False

toId :: Reference -> Maybe Id
toId :: Reference' Text Hash -> Maybe Id
toId =
  Getting (First Id) (Reference' Text Hash) Id
-> Reference' Text Hash -> Maybe Id
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview Getting (First Id) (Reference' Text Hash) Id
forall t h h' (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Id' h) (f (Id' h')) -> p (Reference' t h) (f (Reference' t h'))
_ReferenceDerived

toShortHash :: Reference -> ShortHash
toShortHash :: Reference' Text Hash -> ShortHash
toShortHash = \case
  ReferenceBuiltin Text
b -> Text -> ShortHash
SH.Builtin Text
b
  ReferenceDerived (Id Hash
h Pos
0) -> Text -> Maybe Pos -> Maybe Pos -> ShortHash
SH.ShortHash (Hash -> Text
Hash.toBase32HexText Hash
h) Maybe Pos
forall a. Maybe a
Nothing Maybe Pos
forall a. Maybe a
Nothing
  ReferenceDerived (Id Hash
h Pos
i) -> Text -> Maybe Pos -> Maybe Pos -> ShortHash
SH.ShortHash (Hash -> Text
Hash.toBase32HexText Hash
h) (Pos -> Maybe Pos
forall a. a -> Maybe a
Just Pos
i) Maybe Pos
forall a. Maybe a
Nothing

unsafeId :: Reference -> Id
unsafeId :: Reference' Text Hash -> Id
unsafeId = \case
  ReferenceBuiltin Text
b -> [Char] -> Id
forall a. HasCallStack => [Char] -> a
error ([Char] -> Id) -> [Char] -> Id
forall a b. (a -> b) -> a -> b
$ [Char]
"Tried to get the hash of builtin " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> [Char]
Text.unpack Text
b [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
"."
  ReferenceDerived Id
x -> Id
x

instance Bifunctor Reference' where
  bimap :: forall a b c d.
(a -> b) -> (c -> d) -> Reference' a c -> Reference' b d
bimap a -> b
f c -> d
_ (ReferenceBuiltin a
t) = b -> Reference' b d
forall t h. t -> Reference' t h
ReferenceBuiltin (a -> b
f a
t)
  bimap a -> b
_ c -> d
g (ReferenceDerived Id' c
id) = Id' d -> Reference' b d
forall t h. Id' h -> Reference' t h
ReferenceDerived (c -> d
g (c -> d) -> Id' c -> Id' d
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Id' c
id)

instance Bifoldable Reference' where
  bifoldMap :: forall m a b.
Monoid m =>
(a -> m) -> (b -> m) -> Reference' a b -> m
bifoldMap a -> m
f b -> m
_ (ReferenceBuiltin a
t) = a -> m
f a
t
  bifoldMap a -> m
_ b -> m
g (ReferenceDerived Id' b
id) = (b -> m) -> Id' b -> m
forall m a. Monoid m => (a -> m) -> Id' a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap b -> m
g Id' b
id

instance Bitraversable Reference' where
  bitraverse :: forall (f :: * -> *) a c b d.
Applicative f =>
(a -> f c) -> (b -> f d) -> Reference' a b -> f (Reference' c d)
bitraverse a -> f c
f b -> f d
_ (ReferenceBuiltin a
t) = c -> Reference' c d
forall t h. t -> Reference' t h
ReferenceBuiltin (c -> Reference' c d) -> f c -> f (Reference' c d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f c
f a
t
  bitraverse a -> f c
_ b -> f d
g (ReferenceDerived Id' b
id) = Id' d -> Reference' c d
forall t h. Id' h -> Reference' t h
ReferenceDerived (Id' d -> Reference' c d) -> f (Id' d) -> f (Reference' c d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (b -> f d) -> Id' b -> f (Id' d)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Id' a -> f (Id' b)
traverse b -> f d
g Id' b
id

component :: H.Hash -> [k] -> [(k, Id)]
component :: forall k. Hash -> [k] -> [(k, Id)]
component Hash
h [k]
ks =
  let
   in [(k
k, (Hash -> Pos -> Id
forall h. h -> Pos -> Id' h
Id Hash
h Pos
i)) | (k
k, Pos
i) <- [k]
ks [k] -> [Pos] -> [(k, Pos)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [Pos
0 ..]]