module Unison.HashQualifiedPrime where
import Data.Text qualified as Text
import Unison.HashQualified qualified as HQ
import Unison.Name (Name)
import Unison.Name qualified as Name
import Unison.NameSegment (NameSegment)
import Unison.Prelude
import Unison.Reference (Reference)
import Unison.Reference qualified as Reference
import Unison.Referent (Referent)
import Unison.Referent qualified as Referent
import Unison.ShortHash (ShortHash)
import Unison.ShortHash qualified as SH
import Prelude hiding (take)
data HashQualified n = NameOnly n | HashQualified n ShortHash
deriving stock (HashQualified n -> HashQualified n -> Bool
(HashQualified n -> HashQualified n -> Bool)
-> (HashQualified n -> HashQualified n -> Bool)
-> Eq (HashQualified n)
forall n. Eq n => HashQualified n -> HashQualified n -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall n. Eq n => HashQualified n -> HashQualified n -> Bool
== :: HashQualified n -> HashQualified n -> Bool
$c/= :: forall n. Eq n => HashQualified n -> HashQualified n -> Bool
/= :: HashQualified n -> HashQualified n -> Bool
Eq, (forall a b. (a -> b) -> HashQualified a -> HashQualified b)
-> (forall a b. a -> HashQualified b -> HashQualified a)
-> Functor HashQualified
forall a b. a -> HashQualified b -> HashQualified a
forall a b. (a -> b) -> HashQualified a -> HashQualified 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) -> HashQualified a -> HashQualified b
fmap :: forall a b. (a -> b) -> HashQualified a -> HashQualified b
$c<$ :: forall a b. a -> HashQualified b -> HashQualified a
<$ :: forall a b. a -> HashQualified b -> HashQualified a
Functor, (forall x. HashQualified n -> Rep (HashQualified n) x)
-> (forall x. Rep (HashQualified n) x -> HashQualified n)
-> Generic (HashQualified n)
forall x. Rep (HashQualified n) x -> HashQualified n
forall x. HashQualified n -> Rep (HashQualified n) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall n x. Rep (HashQualified n) x -> HashQualified n
forall n x. HashQualified n -> Rep (HashQualified n) x
$cfrom :: forall n x. HashQualified n -> Rep (HashQualified n) x
from :: forall x. HashQualified n -> Rep (HashQualified n) x
$cto :: forall n x. Rep (HashQualified n) x -> HashQualified n
to :: forall x. Rep (HashQualified n) x -> HashQualified n
Generic, (forall m. Monoid m => HashQualified m -> m)
-> (forall m a. Monoid m => (a -> m) -> HashQualified a -> m)
-> (forall m a. Monoid m => (a -> m) -> HashQualified a -> m)
-> (forall a b. (a -> b -> b) -> b -> HashQualified a -> b)
-> (forall a b. (a -> b -> b) -> b -> HashQualified a -> b)
-> (forall b a. (b -> a -> b) -> b -> HashQualified a -> b)
-> (forall b a. (b -> a -> b) -> b -> HashQualified a -> b)
-> (forall a. (a -> a -> a) -> HashQualified a -> a)
-> (forall a. (a -> a -> a) -> HashQualified a -> a)
-> (forall a. HashQualified a -> [a])
-> (forall a. HashQualified a -> Bool)
-> (forall a. HashQualified a -> Int)
-> (forall a. Eq a => a -> HashQualified a -> Bool)
-> (forall a. Ord a => HashQualified a -> a)
-> (forall a. Ord a => HashQualified a -> a)
-> (forall a. Num a => HashQualified a -> a)
-> (forall a. Num a => HashQualified a -> a)
-> Foldable HashQualified
forall a. Eq a => a -> HashQualified a -> Bool
forall a. Num a => HashQualified a -> a
forall a. Ord a => HashQualified a -> a
forall m. Monoid m => HashQualified m -> m
forall a. HashQualified a -> Bool
forall a. HashQualified a -> Int
forall a. HashQualified a -> [a]
forall a. (a -> a -> a) -> HashQualified a -> a
forall m a. Monoid m => (a -> m) -> HashQualified a -> m
forall b a. (b -> a -> b) -> b -> HashQualified a -> b
forall a b. (a -> b -> b) -> b -> HashQualified 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 => HashQualified m -> m
fold :: forall m. Monoid m => HashQualified m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> HashQualified a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> HashQualified a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> HashQualified a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> HashQualified a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> HashQualified a -> b
foldr :: forall a b. (a -> b -> b) -> b -> HashQualified a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> HashQualified a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> HashQualified a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> HashQualified a -> b
foldl :: forall b a. (b -> a -> b) -> b -> HashQualified a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> HashQualified a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> HashQualified a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> HashQualified a -> a
foldr1 :: forall a. (a -> a -> a) -> HashQualified a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> HashQualified a -> a
foldl1 :: forall a. (a -> a -> a) -> HashQualified a -> a
$ctoList :: forall a. HashQualified a -> [a]
toList :: forall a. HashQualified a -> [a]
$cnull :: forall a. HashQualified a -> Bool
null :: forall a. HashQualified a -> Bool
$clength :: forall a. HashQualified a -> Int
length :: forall a. HashQualified a -> Int
$celem :: forall a. Eq a => a -> HashQualified a -> Bool
elem :: forall a. Eq a => a -> HashQualified a -> Bool
$cmaximum :: forall a. Ord a => HashQualified a -> a
maximum :: forall a. Ord a => HashQualified a -> a
$cminimum :: forall a. Ord a => HashQualified a -> a
minimum :: forall a. Ord a => HashQualified a -> a
$csum :: forall a. Num a => HashQualified a -> a
sum :: forall a. Num a => HashQualified a -> a
$cproduct :: forall a. Num a => HashQualified a -> a
product :: forall a. Num a => HashQualified a -> a
Foldable, Eq (HashQualified n)
Eq (HashQualified n) =>
(HashQualified n -> HashQualified n -> Ordering)
-> (HashQualified n -> HashQualified n -> Bool)
-> (HashQualified n -> HashQualified n -> Bool)
-> (HashQualified n -> HashQualified n -> Bool)
-> (HashQualified n -> HashQualified n -> Bool)
-> (HashQualified n -> HashQualified n -> HashQualified n)
-> (HashQualified n -> HashQualified n -> HashQualified n)
-> Ord (HashQualified n)
HashQualified n -> HashQualified n -> Bool
HashQualified n -> HashQualified n -> Ordering
HashQualified n -> HashQualified n -> HashQualified n
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 n. Ord n => Eq (HashQualified n)
forall n. Ord n => HashQualified n -> HashQualified n -> Bool
forall n. Ord n => HashQualified n -> HashQualified n -> Ordering
forall n.
Ord n =>
HashQualified n -> HashQualified n -> HashQualified n
$ccompare :: forall n. Ord n => HashQualified n -> HashQualified n -> Ordering
compare :: HashQualified n -> HashQualified n -> Ordering
$c< :: forall n. Ord n => HashQualified n -> HashQualified n -> Bool
< :: HashQualified n -> HashQualified n -> Bool
$c<= :: forall n. Ord n => HashQualified n -> HashQualified n -> Bool
<= :: HashQualified n -> HashQualified n -> Bool
$c> :: forall n. Ord n => HashQualified n -> HashQualified n -> Bool
> :: HashQualified n -> HashQualified n -> Bool
$c>= :: forall n. Ord n => HashQualified n -> HashQualified n -> Bool
>= :: HashQualified n -> HashQualified n -> Bool
$cmax :: forall n.
Ord n =>
HashQualified n -> HashQualified n -> HashQualified n
max :: HashQualified n -> HashQualified n -> HashQualified n
$cmin :: forall n.
Ord n =>
HashQualified n -> HashQualified n -> HashQualified n
min :: HashQualified n -> HashQualified n -> HashQualified n
Ord, Int -> HashQualified n -> ShowS
[HashQualified n] -> ShowS
HashQualified n -> String
(Int -> HashQualified n -> ShowS)
-> (HashQualified n -> String)
-> ([HashQualified n] -> ShowS)
-> Show (HashQualified n)
forall n. Show n => Int -> HashQualified n -> ShowS
forall n. Show n => [HashQualified n] -> ShowS
forall n. Show n => HashQualified n -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall n. Show n => Int -> HashQualified n -> ShowS
showsPrec :: Int -> HashQualified n -> ShowS
$cshow :: forall n. Show n => HashQualified n -> String
show :: HashQualified n -> String
$cshowList :: forall n. Show n => [HashQualified n] -> ShowS
showList :: [HashQualified n] -> ShowS
Show, Functor HashQualified
Foldable HashQualified
(Functor HashQualified, Foldable HashQualified) =>
(forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HashQualified a -> f (HashQualified b))
-> (forall (f :: * -> *) a.
Applicative f =>
HashQualified (f a) -> f (HashQualified a))
-> (forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HashQualified a -> m (HashQualified b))
-> (forall (m :: * -> *) a.
Monad m =>
HashQualified (m a) -> m (HashQualified a))
-> Traversable HashQualified
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 =>
HashQualified (m a) -> m (HashQualified a)
forall (f :: * -> *) a.
Applicative f =>
HashQualified (f a) -> f (HashQualified a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HashQualified a -> m (HashQualified b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HashQualified a -> f (HashQualified b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HashQualified a -> f (HashQualified b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> HashQualified a -> f (HashQualified b)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
HashQualified (f a) -> f (HashQualified a)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
HashQualified (f a) -> f (HashQualified a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HashQualified a -> m (HashQualified b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> HashQualified a -> m (HashQualified b)
$csequence :: forall (m :: * -> *) a.
Monad m =>
HashQualified (m a) -> m (HashQualified a)
sequence :: forall (m :: * -> *) a.
Monad m =>
HashQualified (m a) -> m (HashQualified a)
Traversable)
type HQSegment = HashQualified NameSegment
toHQ :: HashQualified n -> HQ.HashQualified n
toHQ :: forall n. HashQualified n -> HashQualified n
toHQ = \case
NameOnly n
n -> n -> HashQualified n
forall n. n -> HashQualified n
HQ.NameOnly n
n
HashQualified n
n ShortHash
sh -> n -> ShortHash -> HashQualified n
forall n. n -> ShortHash -> HashQualified n
HQ.HashQualified n
n ShortHash
sh
fromHQ :: HQ.HashQualified n -> Maybe (HashQualified n)
fromHQ :: forall n. HashQualified n -> Maybe (HashQualified n)
fromHQ = \case
HQ.NameOnly n
n -> HashQualified n -> Maybe (HashQualified n)
forall a. a -> Maybe a
Just (HashQualified n -> Maybe (HashQualified n))
-> HashQualified n -> Maybe (HashQualified n)
forall a b. (a -> b) -> a -> b
$ n -> HashQualified n
forall n. n -> HashQualified n
NameOnly n
n
HQ.HashQualified n
n ShortHash
sh -> HashQualified n -> Maybe (HashQualified n)
forall a. a -> Maybe a
Just (HashQualified n -> Maybe (HashQualified n))
-> HashQualified n -> Maybe (HashQualified n)
forall a b. (a -> b) -> a -> b
$ n -> ShortHash -> HashQualified n
forall n. n -> ShortHash -> HashQualified n
HashQualified n
n ShortHash
sh
HQ.HashOnly {} -> Maybe (HashQualified n)
forall a. Maybe a
Nothing
fromHQ2 :: HQ.HashQualified n -> Either ShortHash (HashQualified n)
fromHQ2 :: forall n. HashQualified n -> Either ShortHash (HashQualified n)
fromHQ2 = \case
HQ.NameOnly n
n -> HashQualified n -> Either ShortHash (HashQualified n)
forall a b. b -> Either a b
Right (HashQualified n -> Either ShortHash (HashQualified n))
-> HashQualified n -> Either ShortHash (HashQualified n)
forall a b. (a -> b) -> a -> b
$ n -> HashQualified n
forall n. n -> HashQualified n
NameOnly n
n
HQ.HashQualified n
n ShortHash
sh -> HashQualified n -> Either ShortHash (HashQualified n)
forall a b. b -> Either a b
Right (HashQualified n -> Either ShortHash (HashQualified n))
-> HashQualified n -> Either ShortHash (HashQualified n)
forall a b. (a -> b) -> a -> b
$ n -> ShortHash -> HashQualified n
forall n. n -> ShortHash -> HashQualified n
HashQualified n
n ShortHash
sh
HQ.HashOnly ShortHash
sh -> ShortHash -> Either ShortHash (HashQualified n)
forall a b. a -> Either a b
Left ShortHash
sh
toName :: HashQualified n -> n
toName :: forall n. HashQualified n -> n
toName = \case
NameOnly n
name -> n
name
HashQualified n
name ShortHash
_ -> n
name
nameLength :: (Name -> Text) -> HashQualified Name -> Int
nameLength :: (Name -> Text) -> HashQualified Name -> Int
nameLength Name -> Text
nameToText = Text -> Int
Text.length (Text -> Int)
-> (HashQualified Name -> Text) -> HashQualified Name -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Name -> Text) -> HashQualified Name -> Text
forall n. (n -> Text) -> HashQualified n -> Text
toTextWith Name -> Text
nameToText
take :: Int -> HashQualified n -> HashQualified n
take :: forall n. Int -> HashQualified n -> HashQualified n
take Int
i = \case
n :: HashQualified n
n@(NameOnly n
_) -> HashQualified n
n
HashQualified n
n ShortHash
s -> if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then n -> HashQualified n
forall n. n -> HashQualified n
NameOnly n
n else n -> ShortHash -> HashQualified n
forall n. n -> ShortHash -> HashQualified n
HashQualified n
n (Int -> ShortHash -> ShortHash
SH.shortenTo Int
i ShortHash
s)
toNameOnly :: HashQualified n -> HashQualified n
toNameOnly :: forall n. HashQualified n -> HashQualified n
toNameOnly = n -> HashQualified n
forall n. n -> HashQualified n
fromName (n -> HashQualified n)
-> (HashQualified n -> n) -> HashQualified n -> HashQualified n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashQualified n -> n
forall n. HashQualified n -> n
toName
toHash :: HashQualified n -> Maybe ShortHash
toHash :: forall n. HashQualified n -> Maybe ShortHash
toHash = \case
NameOnly n
_ -> Maybe ShortHash
forall a. Maybe a
Nothing
HashQualified n
_ ShortHash
sh -> ShortHash -> Maybe ShortHash
forall a. a -> Maybe a
Just ShortHash
sh
toStringWith :: (n -> String) -> HashQualified n -> String
toStringWith :: forall n. (n -> String) -> HashQualified n -> String
toStringWith n -> String
f = Text -> String
Text.unpack (Text -> String)
-> (HashQualified n -> Text) -> HashQualified n -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (n -> Text) -> HashQualified n -> Text
forall n. (n -> Text) -> HashQualified n -> Text
toTextWith (String -> Text
Text.pack (String -> Text) -> (n -> String) -> n -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> String
f)
toTextWith :: (n -> Text) -> HashQualified n -> Text
toTextWith :: forall n. (n -> Text) -> HashQualified n -> Text
toTextWith n -> Text
f = \case
NameOnly n
name -> n -> Text
f n
name
HashQualified n
name ShortHash
hash -> n -> Text
f n
name Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ShortHash -> Text
SH.toText ShortHash
hash
fromNamedReferent :: n -> Referent -> HashQualified n
fromNamedReferent :: forall n. n -> Referent -> HashQualified n
fromNamedReferent n
n Referent
r = n -> ShortHash -> HashQualified n
forall n. n -> ShortHash -> HashQualified n
HashQualified n
n (Referent -> ShortHash
Referent.toShortHash Referent
r)
fromNamedReference :: n -> Reference -> HashQualified n
fromNamedReference :: forall n. n -> Reference -> HashQualified n
fromNamedReference n
n Reference
r = n -> ShortHash -> HashQualified n
forall n. n -> ShortHash -> HashQualified n
HashQualified n
n (Reference -> ShortHash
Reference.toShortHash Reference
r)
fromName :: n -> HashQualified n
fromName :: forall n. n -> HashQualified n
fromName = n -> HashQualified n
forall n. n -> HashQualified n
NameOnly
fromNameHash :: n -> Maybe ShortHash -> HashQualified n
fromNameHash :: forall n. n -> Maybe ShortHash -> HashQualified n
fromNameHash n
name = \case
Maybe ShortHash
Nothing -> n -> HashQualified n
forall n. n -> HashQualified n
NameOnly n
name
Just ShortHash
hash -> n -> ShortHash -> HashQualified n
forall n. n -> ShortHash -> HashQualified n
HashQualified n
name ShortHash
hash
matchesNamedReferent :: (Eq n) => n -> Referent -> HashQualified n -> Bool
matchesNamedReferent :: forall n. Eq n => n -> Referent -> HashQualified n -> Bool
matchesNamedReferent n
n Referent
r = \case
NameOnly n
n' -> n
n' n -> n -> Bool
forall a. Eq a => a -> a -> Bool
== n
n
HashQualified n
n' ShortHash
sh -> n
n' n -> n -> Bool
forall a. Eq a => a -> a -> Bool
== n
n Bool -> Bool -> Bool
&& ShortHash
sh ShortHash -> ShortHash -> Bool
`SH.isPrefixOf` Referent -> ShortHash
Referent.toShortHash Referent
r
matchesNamedReference :: (Eq n) => n -> Reference -> HashQualified n -> Bool
matchesNamedReference :: forall n. Eq n => n -> Reference -> HashQualified n -> Bool
matchesNamedReference n
n Reference
r = \case
NameOnly n
n' -> n
n' n -> n -> Bool
forall a. Eq a => a -> a -> Bool
== n
n
HashQualified n
n' ShortHash
sh -> n
n' n -> n -> Bool
forall a. Eq a => a -> a -> Bool
== n
n Bool -> Bool -> Bool
&& ShortHash
sh ShortHash -> ShortHash -> Bool
`SH.isPrefixOf` Reference -> ShortHash
Reference.toShortHash Reference
r
requalify :: HashQualified Name -> Referent -> HashQualified Name
requalify :: HashQualified Name -> Referent -> HashQualified Name
requalify HashQualified Name
hq Referent
r = case HashQualified Name
hq of
NameOnly Name
n -> Name -> Referent -> HashQualified Name
forall n. n -> Referent -> HashQualified n
fromNamedReferent Name
n Referent
r
HashQualified Name
n ShortHash
_ -> Name -> Referent -> HashQualified Name
forall n. n -> Referent -> HashQualified n
fromNamedReferent Name
n Referent
r
sortByLength :: [HashQualified Name] -> [HashQualified Name]
sortByLength :: [HashQualified Name] -> [HashQualified Name]
sortByLength =
(HashQualified Name -> (Int, Maybe ShortHash, Bool))
-> [HashQualified Name] -> [HashQualified Name]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn \case
NameOnly Name
name -> (NonEmpty NameSegment -> Int
forall a. NonEmpty a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Name -> NonEmpty NameSegment
Name.reverseSegments Name
name), Maybe ShortHash
forall a. Maybe a
Nothing, Name -> Bool
Name.isAbsolute Name
name)
HashQualified Name
name ShortHash
hash -> (NonEmpty NameSegment -> Int
forall a. NonEmpty a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Name -> NonEmpty NameSegment
Name.reverseSegments Name
name), ShortHash -> Maybe ShortHash
forall a. a -> Maybe a
Just ShortHash
hash, Name -> Bool
Name.isAbsolute Name
name)
instance (Name.Alphabetical n) => Name.Alphabetical (HashQualified n) where
compareAlphabetical :: HashQualified n -> HashQualified n -> Ordering
compareAlphabetical (NameOnly n
n) (NameOnly n
n2) = n -> n -> Ordering
forall n. Alphabetical n => n -> n -> Ordering
Name.compareAlphabetical n
n n
n2
compareAlphabetical NameOnly {} HashQualified {} = Ordering
LT
compareAlphabetical HashQualified {} NameOnly {} = Ordering
GT
compareAlphabetical (HashQualified n
n ShortHash
sh) (HashQualified n
n2 ShortHash
sh2) = n -> n -> Ordering
forall n. Alphabetical n => n -> n -> Ordering
Name.compareAlphabetical n
n n
n2 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> ShortHash -> ShortHash -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ShortHash
sh ShortHash
sh2