module Unison.Hashing.V2.Term
  ( Term,
    TermF (..),
    MatchCase (..),
    hashClosedTerm,
    hashTermComponents,
    hashTermComponentsWithoutTypes,
  )
where

import Data.Sequence qualified as Sequence
import Data.Text qualified as Text
import Data.Zip qualified as Zip
import Unison.ABT qualified as ABT
import Unison.Blank qualified as B
import Unison.DataDeclaration.ConstructorId (ConstructorId)
import Unison.Hash (Hash)
import Unison.Hash qualified as Hash
import Unison.Hashing.V2.ABT qualified as ABT
import Unison.Hashing.V2.Pattern (Pattern)
import Unison.Hashing.V2.Reference (Reference (..), ReferenceId (..), pattern ReferenceDerived)
import Unison.Hashing.V2.Reference.Util qualified as ReferenceUtil
import Unison.Hashing.V2.Referent (Referent)
import Unison.Hashing.V2.Tokenizable (Hashable1, accumulateToken)
import Unison.Hashing.V2.Tokenizable qualified as Hashable
import Unison.Hashing.V2.Type (Type)
import Unison.Prelude
import Unison.Var (Var)
import Prelude hiding (and, or)

data MatchCase loc a = MatchCase (Pattern loc) (Maybe a) a
  deriving stock (Int -> MatchCase loc a -> ShowS
[MatchCase loc a] -> ShowS
MatchCase loc a -> String
(Int -> MatchCase loc a -> ShowS)
-> (MatchCase loc a -> String)
-> ([MatchCase loc a] -> ShowS)
-> Show (MatchCase loc a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall loc a. (Show loc, Show a) => Int -> MatchCase loc a -> ShowS
forall loc a. (Show loc, Show a) => [MatchCase loc a] -> ShowS
forall loc a. (Show loc, Show a) => MatchCase loc a -> String
$cshowsPrec :: forall loc a. (Show loc, Show a) => Int -> MatchCase loc a -> ShowS
showsPrec :: Int -> MatchCase loc a -> ShowS
$cshow :: forall loc a. (Show loc, Show a) => MatchCase loc a -> String
show :: MatchCase loc a -> String
$cshowList :: forall loc a. (Show loc, Show a) => [MatchCase loc a] -> ShowS
showList :: [MatchCase loc a] -> ShowS
Show, MatchCase loc a -> MatchCase loc a -> Bool
(MatchCase loc a -> MatchCase loc a -> Bool)
-> (MatchCase loc a -> MatchCase loc a -> Bool)
-> Eq (MatchCase loc a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall loc a. Eq a => MatchCase loc a -> MatchCase loc a -> Bool
$c== :: forall loc a. Eq a => MatchCase loc a -> MatchCase loc a -> Bool
== :: MatchCase loc a -> MatchCase loc a -> Bool
$c/= :: forall loc a. Eq a => MatchCase loc a -> MatchCase loc a -> Bool
/= :: MatchCase loc a -> MatchCase loc a -> Bool
Eq, (forall m. Monoid m => MatchCase loc m -> m)
-> (forall m a. Monoid m => (a -> m) -> MatchCase loc a -> m)
-> (forall m a. Monoid m => (a -> m) -> MatchCase loc a -> m)
-> (forall a b. (a -> b -> b) -> b -> MatchCase loc a -> b)
-> (forall a b. (a -> b -> b) -> b -> MatchCase loc a -> b)
-> (forall b a. (b -> a -> b) -> b -> MatchCase loc a -> b)
-> (forall b a. (b -> a -> b) -> b -> MatchCase loc a -> b)
-> (forall a. (a -> a -> a) -> MatchCase loc a -> a)
-> (forall a. (a -> a -> a) -> MatchCase loc a -> a)
-> (forall a. MatchCase loc a -> [a])
-> (forall a. MatchCase loc a -> Bool)
-> (forall a. MatchCase loc a -> Int)
-> (forall a. Eq a => a -> MatchCase loc a -> Bool)
-> (forall a. Ord a => MatchCase loc a -> a)
-> (forall a. Ord a => MatchCase loc a -> a)
-> (forall a. Num a => MatchCase loc a -> a)
-> (forall a. Num a => MatchCase loc a -> a)
-> Foldable (MatchCase loc)
forall a. Eq a => a -> MatchCase loc a -> Bool
forall a. Num a => MatchCase loc a -> a
forall a. Ord a => MatchCase loc a -> a
forall m. Monoid m => MatchCase loc m -> m
forall a. MatchCase loc a -> Bool
forall a. MatchCase loc a -> Int
forall a. MatchCase loc a -> [a]
forall a. (a -> a -> a) -> MatchCase loc a -> a
forall loc a. Eq a => a -> MatchCase loc a -> Bool
forall loc a. Num a => MatchCase loc a -> a
forall loc a. Ord a => MatchCase loc a -> a
forall m a. Monoid m => (a -> m) -> MatchCase loc a -> m
forall loc m. Monoid m => MatchCase loc m -> m
forall loc a. MatchCase loc a -> Bool
forall loc a. MatchCase loc a -> Int
forall loc a. MatchCase loc a -> [a]
forall b a. (b -> a -> b) -> b -> MatchCase loc a -> b
forall a b. (a -> b -> b) -> b -> MatchCase loc a -> b
forall loc a. (a -> a -> a) -> MatchCase loc a -> a
forall loc m a. Monoid m => (a -> m) -> MatchCase loc a -> m
forall loc b a. (b -> a -> b) -> b -> MatchCase loc a -> b
forall loc a b. (a -> b -> b) -> b -> MatchCase loc 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 loc m. Monoid m => MatchCase loc m -> m
fold :: forall m. Monoid m => MatchCase loc m -> m
$cfoldMap :: forall loc m a. Monoid m => (a -> m) -> MatchCase loc a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> MatchCase loc a -> m
$cfoldMap' :: forall loc m a. Monoid m => (a -> m) -> MatchCase loc a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> MatchCase loc a -> m
$cfoldr :: forall loc a b. (a -> b -> b) -> b -> MatchCase loc a -> b
foldr :: forall a b. (a -> b -> b) -> b -> MatchCase loc a -> b
$cfoldr' :: forall loc a b. (a -> b -> b) -> b -> MatchCase loc a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> MatchCase loc a -> b
$cfoldl :: forall loc b a. (b -> a -> b) -> b -> MatchCase loc a -> b
foldl :: forall b a. (b -> a -> b) -> b -> MatchCase loc a -> b
$cfoldl' :: forall loc b a. (b -> a -> b) -> b -> MatchCase loc a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> MatchCase loc a -> b
$cfoldr1 :: forall loc a. (a -> a -> a) -> MatchCase loc a -> a
foldr1 :: forall a. (a -> a -> a) -> MatchCase loc a -> a
$cfoldl1 :: forall loc a. (a -> a -> a) -> MatchCase loc a -> a
foldl1 :: forall a. (a -> a -> a) -> MatchCase loc a -> a
$ctoList :: forall loc a. MatchCase loc a -> [a]
toList :: forall a. MatchCase loc a -> [a]
$cnull :: forall loc a. MatchCase loc a -> Bool
null :: forall a. MatchCase loc a -> Bool
$clength :: forall loc a. MatchCase loc a -> Int
length :: forall a. MatchCase loc a -> Int
$celem :: forall loc a. Eq a => a -> MatchCase loc a -> Bool
elem :: forall a. Eq a => a -> MatchCase loc a -> Bool
$cmaximum :: forall loc a. Ord a => MatchCase loc a -> a
maximum :: forall a. Ord a => MatchCase loc a -> a
$cminimum :: forall loc a. Ord a => MatchCase loc a -> a
minimum :: forall a. Ord a => MatchCase loc a -> a
$csum :: forall loc a. Num a => MatchCase loc a -> a
sum :: forall a. Num a => MatchCase loc a -> a
$cproduct :: forall loc a. Num a => MatchCase loc a -> a
product :: forall a. Num a => MatchCase loc a -> a
Foldable, (forall a b. (a -> b) -> MatchCase loc a -> MatchCase loc b)
-> (forall a b. a -> MatchCase loc b -> MatchCase loc a)
-> Functor (MatchCase loc)
forall a b. a -> MatchCase loc b -> MatchCase loc a
forall a b. (a -> b) -> MatchCase loc a -> MatchCase loc b
forall loc a b. a -> MatchCase loc b -> MatchCase loc a
forall loc a b. (a -> b) -> MatchCase loc a -> MatchCase loc b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall loc a b. (a -> b) -> MatchCase loc a -> MatchCase loc b
fmap :: forall a b. (a -> b) -> MatchCase loc a -> MatchCase loc b
$c<$ :: forall loc a b. a -> MatchCase loc b -> MatchCase loc a
<$ :: forall a b. a -> MatchCase loc b -> MatchCase loc a
Functor, (forall x. MatchCase loc a -> Rep (MatchCase loc a) x)
-> (forall x. Rep (MatchCase loc a) x -> MatchCase loc a)
-> Generic (MatchCase loc a)
forall x. Rep (MatchCase loc a) x -> MatchCase loc a
forall x. MatchCase loc a -> Rep (MatchCase loc a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall loc a x. Rep (MatchCase loc a) x -> MatchCase loc a
forall loc a x. MatchCase loc a -> Rep (MatchCase loc a) x
$cfrom :: forall loc a x. MatchCase loc a -> Rep (MatchCase loc a) x
from :: forall x. MatchCase loc a -> Rep (MatchCase loc a) x
$cto :: forall loc a x. Rep (MatchCase loc a) x -> MatchCase loc a
to :: forall x. Rep (MatchCase loc a) x -> MatchCase loc a
Generic, (forall a. MatchCase loc a -> Rep1 (MatchCase loc) a)
-> (forall a. Rep1 (MatchCase loc) a -> MatchCase loc a)
-> Generic1 (MatchCase loc)
forall a. Rep1 (MatchCase loc) a -> MatchCase loc a
forall a. MatchCase loc a -> Rep1 (MatchCase loc) a
forall loc a. Rep1 (MatchCase loc) a -> MatchCase loc a
forall loc a. MatchCase loc a -> Rep1 (MatchCase loc) a
forall k (f :: k -> *).
(forall (a :: k). f a -> Rep1 f a)
-> (forall (a :: k). Rep1 f a -> f a) -> Generic1 f
$cfrom1 :: forall loc a. MatchCase loc a -> Rep1 (MatchCase loc) a
from1 :: forall a. MatchCase loc a -> Rep1 (MatchCase loc) a
$cto1 :: forall loc a. Rep1 (MatchCase loc) a -> MatchCase loc a
to1 :: forall a. Rep1 (MatchCase loc) a -> MatchCase loc a
Generic1, Functor (MatchCase loc)
Foldable (MatchCase loc)
(Functor (MatchCase loc), Foldable (MatchCase loc)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> MatchCase loc a -> f (MatchCase loc b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    MatchCase loc (f a) -> f (MatchCase loc a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> MatchCase loc a -> m (MatchCase loc b))
-> (forall (m :: * -> *) a.
    Monad m =>
    MatchCase loc (m a) -> m (MatchCase loc a))
-> Traversable (MatchCase loc)
forall loc. Functor (MatchCase loc)
forall loc. Foldable (MatchCase loc)
forall loc (m :: * -> *) a.
Monad m =>
MatchCase loc (m a) -> m (MatchCase loc a)
forall loc (f :: * -> *) a.
Applicative f =>
MatchCase loc (f a) -> f (MatchCase loc a)
forall loc (m :: * -> *) a b.
Monad m =>
(a -> m b) -> MatchCase loc a -> m (MatchCase loc b)
forall loc (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> MatchCase loc a -> f (MatchCase loc b)
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 =>
MatchCase loc (m a) -> m (MatchCase loc a)
forall (f :: * -> *) a.
Applicative f =>
MatchCase loc (f a) -> f (MatchCase loc a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> MatchCase loc a -> m (MatchCase loc b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> MatchCase loc a -> f (MatchCase loc b)
$ctraverse :: forall loc (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> MatchCase loc a -> f (MatchCase loc b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> MatchCase loc a -> f (MatchCase loc b)
$csequenceA :: forall loc (f :: * -> *) a.
Applicative f =>
MatchCase loc (f a) -> f (MatchCase loc a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
MatchCase loc (f a) -> f (MatchCase loc a)
$cmapM :: forall loc (m :: * -> *) a b.
Monad m =>
(a -> m b) -> MatchCase loc a -> m (MatchCase loc b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> MatchCase loc a -> m (MatchCase loc b)
$csequence :: forall loc (m :: * -> *) a.
Monad m =>
MatchCase loc (m a) -> m (MatchCase loc a)
sequence :: forall (m :: * -> *) a.
Monad m =>
MatchCase loc (m a) -> m (MatchCase loc a)
Traversable)

-- | Base functor for terms in the Unison language
-- We need `typeVar` because the term and type variables may differ.
data TermF typeVar typeAnn patternAnn a
  = TermInt Int64
  | TermNat Word64
  | TermFloat Double
  | TermBoolean Bool
  | TermText Text
  | TermChar Char
  | TermBlank (B.Blank typeAnn)
  | TermRef Reference
  | -- First argument identifies the data type,
    -- second argument identifies the constructor
    TermConstructor Reference ConstructorId
  | TermRequest Reference ConstructorId
  | TermHandle a a
  | TermApp a a
  | TermAnn a (Type typeVar typeAnn)
  | TermList (Seq a)
  | TermIf a a a
  | TermAnd a a
  | TermOr a a
  | TermLam a
  | -- Note: let rec blocks have an outer ABT.Cycle which introduces as many
    -- variables as there are bindings
    TermLetRec [a] a
  | -- Note: first parameter is the binding, second is the expression which may refer
    -- to this let bound variable. Constructed as `Let b (abs v e)`
    TermLet a a
  | -- Pattern matching / eliminating data types, example:
    --  case x of
    --    Just n -> rhs1
    --    Nothing -> rhs2
    --
    -- translates to
    --
    --   Match x
    --     [ (Constructor 0 [Var], ABT.abs n rhs1)
    --     , (Constructor 1 [], rhs2) ]
    TermMatch a [MatchCase patternAnn a]
  | TermTermLink Referent
  | TermTypeLink Reference
  deriving ((forall m. Monoid m => TermF typeVar typeAnn patternAnn m -> m)
-> (forall m a.
    Monoid m =>
    (a -> m) -> TermF typeVar typeAnn patternAnn a -> m)
-> (forall m a.
    Monoid m =>
    (a -> m) -> TermF typeVar typeAnn patternAnn a -> m)
-> (forall a b.
    (a -> b -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b)
-> (forall a b.
    (a -> b -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b)
-> (forall b a.
    (b -> a -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b)
-> (forall b a.
    (b -> a -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b)
-> (forall a.
    (a -> a -> a) -> TermF typeVar typeAnn patternAnn a -> a)
-> (forall a.
    (a -> a -> a) -> TermF typeVar typeAnn patternAnn a -> a)
-> (forall a. TermF typeVar typeAnn patternAnn a -> [a])
-> (forall a. TermF typeVar typeAnn patternAnn a -> Bool)
-> (forall a. TermF typeVar typeAnn patternAnn a -> Int)
-> (forall a.
    Eq a =>
    a -> TermF typeVar typeAnn patternAnn a -> Bool)
-> (forall a. Ord a => TermF typeVar typeAnn patternAnn a -> a)
-> (forall a. Ord a => TermF typeVar typeAnn patternAnn a -> a)
-> (forall a. Num a => TermF typeVar typeAnn patternAnn a -> a)
-> (forall a. Num a => TermF typeVar typeAnn patternAnn a -> a)
-> Foldable (TermF typeVar typeAnn patternAnn)
forall a. Eq a => a -> TermF typeVar typeAnn patternAnn a -> Bool
forall a. Num a => TermF typeVar typeAnn patternAnn a -> a
forall a. Ord a => TermF typeVar typeAnn patternAnn a -> a
forall m. Monoid m => TermF typeVar typeAnn patternAnn m -> m
forall a. TermF typeVar typeAnn patternAnn a -> Bool
forall a. TermF typeVar typeAnn patternAnn a -> Int
forall a. TermF typeVar typeAnn patternAnn a -> [a]
forall a. (a -> a -> a) -> TermF typeVar typeAnn patternAnn a -> a
forall m a.
Monoid m =>
(a -> m) -> TermF typeVar typeAnn patternAnn a -> m
forall b a.
(b -> a -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
forall a b.
(a -> b -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
forall typeVar typeAnn patternAnn a.
Eq a =>
a -> TermF typeVar typeAnn patternAnn a -> Bool
forall typeVar typeAnn patternAnn a.
Num a =>
TermF typeVar typeAnn patternAnn a -> a
forall typeVar typeAnn patternAnn a.
Ord a =>
TermF typeVar typeAnn patternAnn a -> a
forall typeVar typeAnn patternAnn m.
Monoid m =>
TermF typeVar typeAnn patternAnn m -> m
forall typeVar typeAnn patternAnn a.
TermF typeVar typeAnn patternAnn a -> Bool
forall typeVar typeAnn patternAnn a.
TermF typeVar typeAnn patternAnn a -> Int
forall typeVar typeAnn patternAnn a.
TermF typeVar typeAnn patternAnn a -> [a]
forall typeVar typeAnn patternAnn a.
(a -> a -> a) -> TermF typeVar typeAnn patternAnn a -> a
forall typeVar typeAnn patternAnn m a.
Monoid m =>
(a -> m) -> TermF typeVar typeAnn patternAnn a -> m
forall typeVar typeAnn patternAnn b a.
(b -> a -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
forall typeVar typeAnn patternAnn a b.
(a -> b -> b) -> b -> TermF typeVar typeAnn patternAnn 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 typeVar typeAnn patternAnn m.
Monoid m =>
TermF typeVar typeAnn patternAnn m -> m
fold :: forall m. Monoid m => TermF typeVar typeAnn patternAnn m -> m
$cfoldMap :: forall typeVar typeAnn patternAnn m a.
Monoid m =>
(a -> m) -> TermF typeVar typeAnn patternAnn a -> m
foldMap :: forall m a.
Monoid m =>
(a -> m) -> TermF typeVar typeAnn patternAnn a -> m
$cfoldMap' :: forall typeVar typeAnn patternAnn m a.
Monoid m =>
(a -> m) -> TermF typeVar typeAnn patternAnn a -> m
foldMap' :: forall m a.
Monoid m =>
(a -> m) -> TermF typeVar typeAnn patternAnn a -> m
$cfoldr :: forall typeVar typeAnn patternAnn a b.
(a -> b -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
foldr :: forall a b.
(a -> b -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
$cfoldr' :: forall typeVar typeAnn patternAnn a b.
(a -> b -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
foldr' :: forall a b.
(a -> b -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
$cfoldl :: forall typeVar typeAnn patternAnn b a.
(b -> a -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
foldl :: forall b a.
(b -> a -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
$cfoldl' :: forall typeVar typeAnn patternAnn b a.
(b -> a -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
foldl' :: forall b a.
(b -> a -> b) -> b -> TermF typeVar typeAnn patternAnn a -> b
$cfoldr1 :: forall typeVar typeAnn patternAnn a.
(a -> a -> a) -> TermF typeVar typeAnn patternAnn a -> a
foldr1 :: forall a. (a -> a -> a) -> TermF typeVar typeAnn patternAnn a -> a
$cfoldl1 :: forall typeVar typeAnn patternAnn a.
(a -> a -> a) -> TermF typeVar typeAnn patternAnn a -> a
foldl1 :: forall a. (a -> a -> a) -> TermF typeVar typeAnn patternAnn a -> a
$ctoList :: forall typeVar typeAnn patternAnn a.
TermF typeVar typeAnn patternAnn a -> [a]
toList :: forall a. TermF typeVar typeAnn patternAnn a -> [a]
$cnull :: forall typeVar typeAnn patternAnn a.
TermF typeVar typeAnn patternAnn a -> Bool
null :: forall a. TermF typeVar typeAnn patternAnn a -> Bool
$clength :: forall typeVar typeAnn patternAnn a.
TermF typeVar typeAnn patternAnn a -> Int
length :: forall a. TermF typeVar typeAnn patternAnn a -> Int
$celem :: forall typeVar typeAnn patternAnn a.
Eq a =>
a -> TermF typeVar typeAnn patternAnn a -> Bool
elem :: forall a. Eq a => a -> TermF typeVar typeAnn patternAnn a -> Bool
$cmaximum :: forall typeVar typeAnn patternAnn a.
Ord a =>
TermF typeVar typeAnn patternAnn a -> a
maximum :: forall a. Ord a => TermF typeVar typeAnn patternAnn a -> a
$cminimum :: forall typeVar typeAnn patternAnn a.
Ord a =>
TermF typeVar typeAnn patternAnn a -> a
minimum :: forall a. Ord a => TermF typeVar typeAnn patternAnn a -> a
$csum :: forall typeVar typeAnn patternAnn a.
Num a =>
TermF typeVar typeAnn patternAnn a -> a
sum :: forall a. Num a => TermF typeVar typeAnn patternAnn a -> a
$cproduct :: forall typeVar typeAnn patternAnn a.
Num a =>
TermF typeVar typeAnn patternAnn a -> a
product :: forall a. Num a => TermF typeVar typeAnn patternAnn a -> a
Foldable, (forall a b.
 (a -> b)
 -> TermF typeVar typeAnn patternAnn a
 -> TermF typeVar typeAnn patternAnn b)
-> (forall a b.
    a
    -> TermF typeVar typeAnn patternAnn b
    -> TermF typeVar typeAnn patternAnn a)
-> Functor (TermF typeVar typeAnn patternAnn)
forall a b.
a
-> TermF typeVar typeAnn patternAnn b
-> TermF typeVar typeAnn patternAnn a
forall a b.
(a -> b)
-> TermF typeVar typeAnn patternAnn a
-> TermF typeVar typeAnn patternAnn b
forall typeVar typeAnn patternAnn a b.
a
-> TermF typeVar typeAnn patternAnn b
-> TermF typeVar typeAnn patternAnn a
forall typeVar typeAnn patternAnn a b.
(a -> b)
-> TermF typeVar typeAnn patternAnn a
-> TermF typeVar typeAnn patternAnn b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall typeVar typeAnn patternAnn a b.
(a -> b)
-> TermF typeVar typeAnn patternAnn a
-> TermF typeVar typeAnn patternAnn b
fmap :: forall a b.
(a -> b)
-> TermF typeVar typeAnn patternAnn a
-> TermF typeVar typeAnn patternAnn b
$c<$ :: forall typeVar typeAnn patternAnn a b.
a
-> TermF typeVar typeAnn patternAnn b
-> TermF typeVar typeAnn patternAnn a
<$ :: forall a b.
a
-> TermF typeVar typeAnn patternAnn b
-> TermF typeVar typeAnn patternAnn a
Functor, (forall x.
 TermF typeVar typeAnn patternAnn a
 -> Rep (TermF typeVar typeAnn patternAnn a) x)
-> (forall x.
    Rep (TermF typeVar typeAnn patternAnn a) x
    -> TermF typeVar typeAnn patternAnn a)
-> Generic (TermF typeVar typeAnn patternAnn a)
forall x.
Rep (TermF typeVar typeAnn patternAnn a) x
-> TermF typeVar typeAnn patternAnn a
forall x.
TermF typeVar typeAnn patternAnn a
-> Rep (TermF typeVar typeAnn patternAnn a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall typeVar typeAnn patternAnn a x.
Rep (TermF typeVar typeAnn patternAnn a) x
-> TermF typeVar typeAnn patternAnn a
forall typeVar typeAnn patternAnn a x.
TermF typeVar typeAnn patternAnn a
-> Rep (TermF typeVar typeAnn patternAnn a) x
$cfrom :: forall typeVar typeAnn patternAnn a x.
TermF typeVar typeAnn patternAnn a
-> Rep (TermF typeVar typeAnn patternAnn a) x
from :: forall x.
TermF typeVar typeAnn patternAnn a
-> Rep (TermF typeVar typeAnn patternAnn a) x
$cto :: forall typeVar typeAnn patternAnn a x.
Rep (TermF typeVar typeAnn patternAnn a) x
-> TermF typeVar typeAnn patternAnn a
to :: forall x.
Rep (TermF typeVar typeAnn patternAnn a) x
-> TermF typeVar typeAnn patternAnn a
Generic, (forall a.
 TermF typeVar typeAnn patternAnn a
 -> Rep1 (TermF typeVar typeAnn patternAnn) a)
-> (forall a.
    Rep1 (TermF typeVar typeAnn patternAnn) a
    -> TermF typeVar typeAnn patternAnn a)
-> Generic1 (TermF typeVar typeAnn patternAnn)
forall a.
Rep1 (TermF typeVar typeAnn patternAnn) a
-> TermF typeVar typeAnn patternAnn a
forall a.
TermF typeVar typeAnn patternAnn a
-> Rep1 (TermF typeVar typeAnn patternAnn) a
forall typeVar typeAnn patternAnn a.
Rep1 (TermF typeVar typeAnn patternAnn) a
-> TermF typeVar typeAnn patternAnn a
forall typeVar typeAnn patternAnn a.
TermF typeVar typeAnn patternAnn a
-> Rep1 (TermF typeVar typeAnn patternAnn) a
forall k (f :: k -> *).
(forall (a :: k). f a -> Rep1 f a)
-> (forall (a :: k). Rep1 f a -> f a) -> Generic1 f
$cfrom1 :: forall typeVar typeAnn patternAnn a.
TermF typeVar typeAnn patternAnn a
-> Rep1 (TermF typeVar typeAnn patternAnn) a
from1 :: forall a.
TermF typeVar typeAnn patternAnn a
-> Rep1 (TermF typeVar typeAnn patternAnn) a
$cto1 :: forall typeVar typeAnn patternAnn a.
Rep1 (TermF typeVar typeAnn patternAnn) a
-> TermF typeVar typeAnn patternAnn a
to1 :: forall a.
Rep1 (TermF typeVar typeAnn patternAnn) a
-> TermF typeVar typeAnn patternAnn a
Generic1, Functor (TermF typeVar typeAnn patternAnn)
Foldable (TermF typeVar typeAnn patternAnn)
(Functor (TermF typeVar typeAnn patternAnn),
 Foldable (TermF typeVar typeAnn patternAnn)) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b)
 -> TermF typeVar typeAnn patternAnn a
 -> f (TermF typeVar typeAnn patternAnn b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    TermF typeVar typeAnn patternAnn (f a)
    -> f (TermF typeVar typeAnn patternAnn a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b)
    -> TermF typeVar typeAnn patternAnn a
    -> m (TermF typeVar typeAnn patternAnn b))
-> (forall (m :: * -> *) a.
    Monad m =>
    TermF typeVar typeAnn patternAnn (m a)
    -> m (TermF typeVar typeAnn patternAnn a))
-> Traversable (TermF typeVar typeAnn patternAnn)
forall typeVar typeAnn patternAnn.
Functor (TermF typeVar typeAnn patternAnn)
forall typeVar typeAnn patternAnn.
Foldable (TermF typeVar typeAnn patternAnn)
forall typeVar typeAnn patternAnn (m :: * -> *) a.
Monad m =>
TermF typeVar typeAnn patternAnn (m a)
-> m (TermF typeVar typeAnn patternAnn a)
forall typeVar typeAnn patternAnn (f :: * -> *) a.
Applicative f =>
TermF typeVar typeAnn patternAnn (f a)
-> f (TermF typeVar typeAnn patternAnn a)
forall typeVar typeAnn patternAnn (m :: * -> *) a b.
Monad m =>
(a -> m b)
-> TermF typeVar typeAnn patternAnn a
-> m (TermF typeVar typeAnn patternAnn b)
forall typeVar typeAnn patternAnn (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> TermF typeVar typeAnn patternAnn a
-> f (TermF typeVar typeAnn patternAnn b)
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 =>
TermF typeVar typeAnn patternAnn (m a)
-> m (TermF typeVar typeAnn patternAnn a)
forall (f :: * -> *) a.
Applicative f =>
TermF typeVar typeAnn patternAnn (f a)
-> f (TermF typeVar typeAnn patternAnn a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b)
-> TermF typeVar typeAnn patternAnn a
-> m (TermF typeVar typeAnn patternAnn b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> TermF typeVar typeAnn patternAnn a
-> f (TermF typeVar typeAnn patternAnn b)
$ctraverse :: forall typeVar typeAnn patternAnn (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> TermF typeVar typeAnn patternAnn a
-> f (TermF typeVar typeAnn patternAnn b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b)
-> TermF typeVar typeAnn patternAnn a
-> f (TermF typeVar typeAnn patternAnn b)
$csequenceA :: forall typeVar typeAnn patternAnn (f :: * -> *) a.
Applicative f =>
TermF typeVar typeAnn patternAnn (f a)
-> f (TermF typeVar typeAnn patternAnn a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
TermF typeVar typeAnn patternAnn (f a)
-> f (TermF typeVar typeAnn patternAnn a)
$cmapM :: forall typeVar typeAnn patternAnn (m :: * -> *) a b.
Monad m =>
(a -> m b)
-> TermF typeVar typeAnn patternAnn a
-> m (TermF typeVar typeAnn patternAnn b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b)
-> TermF typeVar typeAnn patternAnn a
-> m (TermF typeVar typeAnn patternAnn b)
$csequence :: forall typeVar typeAnn patternAnn (m :: * -> *) a.
Monad m =>
TermF typeVar typeAnn patternAnn (m a)
-> m (TermF typeVar typeAnn patternAnn a)
sequence :: forall (m :: * -> *) a.
Monad m =>
TermF typeVar typeAnn patternAnn (m a)
-> m (TermF typeVar typeAnn patternAnn a)
Traversable)

-- | Like `Term v`, but with an annotation of type `a` at every level in the tree
type Term v a = Term2 v a a v a

-- | Allow type variables, term variables, type annotations and term annotations
-- to all differ
type Term2 vt at ap v a = ABT.Term (TermF vt at ap) v a

-- some smart constructors
ref :: (Ord v) => a -> Reference -> Term2 vt at ap v a
ref :: forall v a vt at ap. Ord v => a -> Reference -> Term2 vt at ap v a
ref a
a Reference
r = a
-> TermF vt at ap (Term (TermF vt at ap) v a)
-> Term (TermF vt at ap) v a
forall (f :: * -> *) v a.
(Foldable f, Ord v) =>
a -> f (Term f v a) -> Term f v a
ABT.tm' a
a (Reference -> TermF vt at ap (Term (TermF vt at ap) v a)
forall typeVar typeAnn patternAnn a.
Reference -> TermF typeVar typeAnn patternAnn a
TermRef Reference
r)

refId :: (Ord v) => a -> ReferenceId -> Term2 vt at ap v a
refId :: forall v a vt at ap.
Ord v =>
a -> ReferenceId -> Term2 vt at ap v a
refId a
a = a -> Reference -> Term2 vt at ap v a
forall v a vt at ap. Ord v => a -> Reference -> Term2 vt at ap v a
ref a
a (Reference -> Term2 vt at ap v a)
-> (ReferenceId -> Reference) -> ReferenceId -> Term2 vt at ap v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReferenceId -> Reference
ReferenceDerivedId

hashTermComponents ::
  forall v a extra.
  (Var v) =>
  Map v (Term v a, Type v a, extra) ->
  Map v (ReferenceId, Term v a, Type v a, extra)
hashTermComponents :: forall v a extra.
Var v =>
Map v (Term v a, Type v a, extra)
-> Map v (ReferenceId, Term v a, Type v a, extra)
hashTermComponents Map v (Term v a, Type v a, extra)
terms =
  ((Term v a, Type v a, extra)
 -> (ReferenceId, Term v a)
 -> (ReferenceId, Term v a, Type v a, extra))
-> Map v (Term v a, Type v a, extra)
-> Map v (ReferenceId, Term v a)
-> Map v (ReferenceId, Term v a, Type v a, extra)
forall a b c. (a -> b -> c) -> Map v a -> Map v b -> Map v c
forall (f :: * -> *) a b c.
Zip f =>
(a -> b -> c) -> f a -> f b -> f c
Zip.zipWith (Term v a, Type v a, extra)
-> (ReferenceId, Term v a)
-> (ReferenceId, Term v a, Type v a, extra)
keepExtra Map v (Term v a, Type v a, extra)
terms ((ReferenceId -> Term (TermF v a a) v ())
-> Map v (Term v a) -> Map v (ReferenceId, Term v a)
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)
ReferenceUtil.hashComponents (() -> ReferenceId -> Term (TermF v a a) v ()
forall v a vt at ap.
Ord v =>
a -> ReferenceId -> Term2 vt at ap v a
refId ()) Map v (Term v a)
terms')
  where
    terms' :: Map v (Term v a)
    terms' :: Map v (Term v a)
terms' = (Term v a, Type v a, extra) -> Term v a
incorporateType ((Term v a, Type v a, extra) -> Term v a)
-> Map v (Term v a, Type v a, extra) -> Map v (Term v a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map v (Term v a, Type v a, extra)
terms

    keepExtra :: ((Term v a, Type v a, extra) -> (ReferenceId, Term v a) -> (ReferenceId, Term v a, Type v a, extra))
    keepExtra :: (Term v a, Type v a, extra)
-> (ReferenceId, Term v a)
-> (ReferenceId, Term v a, Type v a, extra)
keepExtra (Term v a
_oldTrm, Type v a
typ, extra
extra) (ReferenceId
refId, Term v a
trm) = (ReferenceId
refId, Term v a
trm, Type v a
typ, extra
extra)

    incorporateType :: (Term v a, Type v a, extra) -> Term v a
    incorporateType :: (Term v a, Type v a, extra) -> Term v a
incorporateType (a :: Term v a
a@(Term v a -> ABT (TermF v a a) v (Term v a)
forall (f :: * -> *) v a. Term f v a -> ABT f v (Term f v a)
ABT.out -> ABT.Tm (TermAnn Term v a
e Type v a
_tp)), Type v a
typ, extra
_extra) = a -> TermF v a a (Term v a) -> Term v a
forall (f :: * -> *) v a.
(Foldable f, Ord v) =>
a -> f (Term f v a) -> Term f v a
ABT.tm' (Term v a -> a
forall (f :: * -> *) v a. Term f v a -> a
ABT.annotation Term v a
a) (Term v a -> Type v a -> TermF v a a (Term v a)
forall typeVar typeAnn patternAnn a.
a -> Type typeVar typeAnn -> TermF typeVar typeAnn patternAnn a
TermAnn Term v a
e Type v a
typ)
    incorporateType (Term v a
e, Type v a
typ, extra
_extra) = a -> TermF v a a (Term v a) -> Term v a
forall (f :: * -> *) v a.
(Foldable f, Ord v) =>
a -> f (Term f v a) -> Term f v a
ABT.tm' (Term v a -> a
forall (f :: * -> *) v a. Term f v a -> a
ABT.annotation Term v a
e) (Term v a -> Type v a -> TermF v a a (Term v a)
forall typeVar typeAnn patternAnn a.
a -> Type typeVar typeAnn -> TermF typeVar typeAnn patternAnn a
TermAnn Term v a
e Type v a
typ)

-- keep these until we decide if we want to add the appropriate smart constructors back into this module
-- incorporateType (Term.Ann' e _) typ = Term.ann () e typ
-- incorporateType e typ = Term.ann () e typ

-- Need to insert an "Ann" node inside the 'Tm' ABT wrapper
-- iff there isn't already a top-level annotation.
-- What if there's a top-level Annotation but it doesn't match
-- the type that was provided?

hashTermComponentsWithoutTypes :: (Var v) => Map v (Term v a) -> Map v (ReferenceId, Term v a)
hashTermComponentsWithoutTypes :: forall v a.
Var v =>
Map v (Term v a) -> Map v (ReferenceId, Term v a)
hashTermComponentsWithoutTypes = (ReferenceId -> Term (TermF v a a) v ())
-> Map v (Term (TermF v a a) v a)
-> Map v (ReferenceId, Term (TermF v a a) v a)
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)
ReferenceUtil.hashComponents ((ReferenceId -> Term (TermF v a a) v ())
 -> Map v (Term (TermF v a a) v a)
 -> Map v (ReferenceId, Term (TermF v a a) v a))
-> (ReferenceId -> Term (TermF v a a) v ())
-> Map v (Term (TermF v a a) v a)
-> Map v (ReferenceId, Term (TermF v a a) v a)
forall a b. (a -> b) -> a -> b
$ () -> ReferenceId -> Term (TermF v a a) v ()
forall v a vt at ap.
Ord v =>
a -> ReferenceId -> Term2 vt at ap v a
refId ()

hashClosedTerm :: (Var v) => Term v a -> ReferenceId
hashClosedTerm :: forall v a. Var v => Term v a -> ReferenceId
hashClosedTerm Term v a
tm = Hash -> Pos -> ReferenceId
ReferenceId (Term v a -> Hash
forall (f :: * -> *) v a.
(Functor f, Hashable1 f, Eq v, Show v) =>
Term f v a -> Hash
ABT.hash Term v a
tm) Pos
0

instance (Var v) => Hashable1 (TermF v a p) where
  hash1 :: forall x. ([x] -> ([Hash], x -> Hash)) -> (x -> Hash) -> (TermF v a p) x -> Hash
  hash1 :: forall a.
([a] -> ([Hash], a -> Hash))
-> (a -> Hash) -> TermF v a p a -> Hash
hash1 [x] -> ([Hash], x -> Hash)
hashCycle x -> Hash
hash TermF v a p x
e =
    let varint :: (Integral i) => i -> Hashable.Token
        varint :: forall i. Integral i => i -> Token
varint = Pos -> Token
Hashable.Nat (Pos -> Token) -> (i -> Pos) -> i -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pos
forall a b. (Integral a, Num b) => a -> b
fromIntegral
        tag :: Word8 -> Token
tag = Word8 -> Token
Hashable.Tag
        hashed :: Hash -> Token
hashed = Hash -> Token
Hashable.Hashed
     in case TermF v a p x
e of
          -- So long as `Reference.Derived` ctors are created using the same
          -- hashing function as is used here, this case ensures that references
          -- are 'transparent' wrt hash and hashing is unaffected by whether
          -- expressions are linked. So for example `x = 1 + 1` and `y = x` hash
          -- the same.
          TermRef (ReferenceDerived Hash
h Pos
0) -> ByteString -> Hash
Hash.fromByteString (Hash -> ByteString
Hash.toByteString Hash
h)
          TermRef (ReferenceDerived Hash
h Pos
i) ->
            [Token] -> Hash
Hashable.accumulate
              [ Word8 -> Token
tag Word8
1,
                Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ ByteString -> Hash
Hash.fromByteString (Hash -> ByteString
Hash.toByteString Hash
h),
                Pos -> Token
Hashable.Nat Pos
i
              ]
          -- Note: start each layer with leading `1` byte, to avoid collisions
          -- with types, which start each layer with leading `0`.
          -- See `Hashable1 Type.F`
          TermF v a p x
_ ->
            [Token] -> Hash
Hashable.accumulate ([Token] -> Hash) -> [Token] -> Hash
forall a b. (a -> b) -> a -> b
$
              Word8 -> Token
tag Word8
1
                Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: case TermF v a p x
e of
                  TermNat Pos
i -> [Word8 -> Token
tag Word8
64, Pos -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Pos
i]
                  TermInt Int64
i -> [Word8 -> Token
tag Word8
65, Int64 -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Int64
i]
                  TermFloat Double
n -> [Word8 -> Token
tag Word8
66, Double -> Token
Hashable.Double Double
n]
                  TermBoolean Bool
b -> [Word8 -> Token
tag Word8
67, Bool -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Bool
b]
                  TermText Text
t -> [Word8 -> Token
tag Word8
68, Text -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Text
t]
                  TermChar Char
c -> [Word8 -> Token
tag Word8
69, Char -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Char
c]
                  TermBlank Blank a
b ->
                    Word8 -> Token
tag Word8
1 Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: case Blank a
b of
                      Blank a
B.Blank -> [Word8 -> Token
tag Word8
0]
                      B.Recorded (B.Placeholder a
_ String
s) ->
                        [Word8 -> Token
tag Word8
1, Text -> Token
Hashable.Text (String -> Text
Text.pack String
s)]
                      B.Recorded (B.Resolve a
_ String
s) ->
                        [Word8 -> Token
tag Word8
2, Text -> Token
Hashable.Text (String -> Text
Text.pack String
s)]
                      B.Recorded (B.MissingResultPlaceholder a
_) -> [Word8 -> Token
tag Word8
3]
                      Blank a
B.Retain -> [Word8 -> Token
tag Word8
4]
                  TermRef (ReferenceBuiltin Text
name) -> [Word8 -> Token
tag Word8
2, Text -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Text
name]
                  TermApp x
a x
a2 -> [Word8 -> Token
tag Word8
3, Hash -> Token
hashed (x -> Hash
hash x
a), Hash -> Token
hashed (x -> Hash
hash x
a2)]
                  TermAnn x
a Type v a
t -> [Word8 -> Token
tag Word8
4, Hash -> Token
hashed (x -> Hash
hash x
a), Hash -> Token
hashed (Type v a -> Hash
forall (f :: * -> *) v a.
(Functor f, Hashable1 f, Eq v, Show v) =>
Term f v a -> Hash
ABT.hash Type v a
t)]
                  TermList Seq x
as ->
                    Word8 -> Token
tag Word8
5
                      Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: Int -> Token
forall i. Integral i => i -> Token
varint (Seq x -> Int
forall a. Seq a -> Int
Sequence.length Seq x
as)
                      Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: (x -> Token) -> [x] -> [Token]
forall a b. (a -> b) -> [a] -> [b]
map
                        (Hash -> Token
hashed (Hash -> Token) -> (x -> Hash) -> x -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Hash
hash)
                        (Seq x -> [x]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Seq x
as)
                  TermLam x
a -> [Word8 -> Token
tag Word8
6, Hash -> Token
hashed (x -> Hash
hash x
a)]
                  -- note: we use `hashCycle` to ensure result is independent of
                  -- let binding order
                  TermLetRec [x]
as x
a -> case [x] -> ([Hash], x -> Hash)
hashCycle [x]
as of
                    ([Hash]
hs, x -> Hash
hash) -> Word8 -> Token
tag Word8
7 Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: Hash -> Token
hashed (x -> Hash
hash x
a) Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: (Hash -> Token) -> [Hash] -> [Token]
forall a b. (a -> b) -> [a] -> [b]
map Hash -> Token
hashed [Hash]
hs
                  -- here, order is significant, so don't use hashCycle
                  TermLet x
b x
a -> [Word8 -> Token
tag Word8
8, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
b, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
a]
                  TermIf x
b x
t x
f ->
                    [Word8 -> Token
tag Word8
9, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
b, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
t, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
f]
                  TermRequest Reference
r Pos
n -> [Word8 -> Token
tag Word8
10, Reference -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Reference
r, Pos -> Token
forall i. Integral i => i -> Token
varint Pos
n]
                  TermConstructor Reference
r Pos
n -> [Word8 -> Token
tag Word8
12, Reference -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Reference
r, Pos -> Token
forall i. Integral i => i -> Token
varint Pos
n]
                  TermMatch x
e [MatchCase p x]
branches ->
                    Word8 -> Token
tag Word8
13 Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: Hash -> Token
hashed (x -> Hash
hash x
e) Token -> [Token] -> [Token]
forall a. a -> [a] -> [a]
: (MatchCase p x -> [Token]) -> [MatchCase p x] -> [Token]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap MatchCase p x -> [Token]
forall {loc}. MatchCase loc x -> [Token]
h [MatchCase p x]
branches
                    where
                      h :: MatchCase loc x -> [Token]
h (MatchCase Pattern loc
pat Maybe x
guard x
branch) =
                        [[Token]] -> [Token]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
                          [ [Pattern loc -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Pattern loc
pat],
                            Maybe Token -> [Token]
forall a. Maybe a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Hash -> Token
hashed (Hash -> Token) -> (x -> Hash) -> x -> Token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. x -> Hash
hash (x -> Token) -> Maybe x -> Maybe Token
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe x
guard),
                            [Hash -> Token
hashed (x -> Hash
hash x
branch)]
                          ]
                  TermHandle x
h x
b -> [Word8 -> Token
tag Word8
15, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
h, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
b]
                  TermAnd x
x x
y -> [Word8 -> Token
tag Word8
16, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
x, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
y]
                  TermOr x
x x
y -> [Word8 -> Token
tag Word8
17, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
x, Hash -> Token
hashed (Hash -> Token) -> Hash -> Token
forall a b. (a -> b) -> a -> b
$ x -> Hash
hash x
y]
                  TermTermLink Referent
r -> [Word8 -> Token
tag Word8
18, Referent -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Referent
r]
                  TermTypeLink Reference
r -> [Word8 -> Token
tag Word8
19, Reference -> Token
forall t. Tokenizable t => t -> Token
accumulateToken Reference
r]