{-# LANGUAGE
  DataKinds,
  DerivingVia,
  FlexibleInstances,
  StandaloneDeriving,
  TypeOperators #-}

-- | Basic configurations to get started.
module DiffLoc.Starter
  ( -- * The heavy lifter
    Diff

    -- * Basic index types
  , Z
  , N
  , N'

    -- * Under the hood
  , (:$:)(..)
  ) where

import GHC.TypeNats (KnownNat)
import DiffLoc.Diff
import DiffLoc.Interval
import DiffLoc.Index
import DiffLoc.Shift
import DiffLoc.Unsafe

-- $setup
-- >>> import DiffLoc
-- >>> import DiffLoc.Unsafe

-- | A shorthand for the common use case of 'Diff'.
type Diff p = ADiff (Replace p)

-- | A trick to reduce noise by hiding newtype wrapper constructors.
-- This makes the documentation more palatable.
--
-- >>> show (NoShow (Plain 3) :: Plain :$: Int)
-- "3"
-- >>> show (Colline 4 2 :.. Vallee (offset 3) (offset 3) :: Interval (Colline N N))
-- "Colline 4 2 :.. Vallee (offset 3) (offset 3)"
newtype f :$: x = NoShow (f x)
  deriving ((f :$: x) -> (f :$: x) -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (f :: * -> *) x. Eq (f x) => (f :$: x) -> (f :$: x) -> Bool
/= :: (f :$: x) -> (f :$: x) -> Bool
$c/= :: forall (f :: * -> *) x. Eq (f x) => (f :$: x) -> (f :$: x) -> Bool
== :: (f :$: x) -> (f :$: x) -> Bool
$c== :: forall (f :: * -> *) x. Eq (f x) => (f :$: x) -> (f :$: x) -> Bool
Eq, (f :$: x) -> (f :$: x) -> Bool
(f :$: x) -> (f :$: x) -> Ordering
(f :$: x) -> (f :$: x) -> f :$: x
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 {f :: * -> *} {x}. Ord (f x) => Eq (f :$: x)
forall (f :: * -> *) x. Ord (f x) => (f :$: x) -> (f :$: x) -> Bool
forall (f :: * -> *) x.
Ord (f x) =>
(f :$: x) -> (f :$: x) -> Ordering
forall (f :: * -> *) x.
Ord (f x) =>
(f :$: x) -> (f :$: x) -> f :$: x
min :: (f :$: x) -> (f :$: x) -> f :$: x
$cmin :: forall (f :: * -> *) x.
Ord (f x) =>
(f :$: x) -> (f :$: x) -> f :$: x
max :: (f :$: x) -> (f :$: x) -> f :$: x
$cmax :: forall (f :: * -> *) x.
Ord (f x) =>
(f :$: x) -> (f :$: x) -> f :$: x
>= :: (f :$: x) -> (f :$: x) -> Bool
$c>= :: forall (f :: * -> *) x. Ord (f x) => (f :$: x) -> (f :$: x) -> Bool
> :: (f :$: x) -> (f :$: x) -> Bool
$c> :: forall (f :: * -> *) x. Ord (f x) => (f :$: x) -> (f :$: x) -> Bool
<= :: (f :$: x) -> (f :$: x) -> Bool
$c<= :: forall (f :: * -> *) x. Ord (f x) => (f :$: x) -> (f :$: x) -> Bool
< :: (f :$: x) -> (f :$: x) -> Bool
$c< :: forall (f :: * -> *) x. Ord (f x) => (f :$: x) -> (f :$: x) -> Bool
compare :: (f :$: x) -> (f :$: x) -> Ordering
$ccompare :: forall (f :: * -> *) x.
Ord (f x) =>
(f :$: x) -> (f :$: x) -> Ordering
Ord)
  deriving (NonEmpty (f :$: x) -> f :$: x
(f :$: x) -> (f :$: x) -> f :$: x
forall b. Integral b => b -> (f :$: x) -> f :$: x
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall (f :: * -> *) x.
Semigroup (f x) =>
NonEmpty (f :$: x) -> f :$: x
forall (f :: * -> *) x.
Semigroup (f x) =>
(f :$: x) -> (f :$: x) -> f :$: x
forall (f :: * -> *) x b.
(Semigroup (f x), Integral b) =>
b -> (f :$: x) -> f :$: x
stimes :: forall b. Integral b => b -> (f :$: x) -> f :$: x
$cstimes :: forall (f :: * -> *) x b.
(Semigroup (f x), Integral b) =>
b -> (f :$: x) -> f :$: x
sconcat :: NonEmpty (f :$: x) -> f :$: x
$csconcat :: forall (f :: * -> *) x.
Semigroup (f x) =>
NonEmpty (f :$: x) -> f :$: x
<> :: (f :$: x) -> (f :$: x) -> f :$: x
$c<> :: forall (f :: * -> *) x.
Semigroup (f x) =>
(f :$: x) -> (f :$: x) -> f :$: x
Semigroup, f :$: x
[f :$: x] -> f :$: x
(f :$: x) -> (f :$: x) -> f :$: x
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall {f :: * -> *} {x}. Monoid (f x) => Semigroup (f :$: x)
forall (f :: * -> *) x. Monoid (f x) => f :$: x
forall (f :: * -> *) x. Monoid (f x) => [f :$: x] -> f :$: x
forall (f :: * -> *) x.
Monoid (f x) =>
(f :$: x) -> (f :$: x) -> f :$: x
mconcat :: [f :$: x] -> f :$: x
$cmconcat :: forall (f :: * -> *) x. Monoid (f x) => [f :$: x] -> f :$: x
mappend :: (f :$: x) -> (f :$: x) -> f :$: x
$cmappend :: forall (f :: * -> *) x.
Monoid (f x) =>
(f :$: x) -> (f :$: x) -> f :$: x
mempty :: f :$: x
$cmempty :: forall (f :: * -> *) x. Monoid (f x) => f :$: x
Monoid, (f :$: x) -> Trans (f :$: x) -> f :$: x
(f :$: x) -> (f :$: x) -> Maybe (Trans (f :$: x))
forall p.
Ord p
-> Ord (Trans p)
-> Monoid (Trans p)
-> (p -> Trans p -> p)
-> (p -> p -> Maybe (Trans p))
-> Amor p
forall {f :: * -> *} {x}. Amor (f x) => Ord (Trans (f :$: x))
forall {f :: * -> *} {x}. Amor (f x) => Ord (f :$: x)
forall {f :: * -> *} {x}. Amor (f x) => Monoid (Trans (f :$: x))
forall (f :: * -> *) x.
Amor (f x) =>
(f :$: x) -> Trans (f :$: x) -> f :$: x
forall (f :: * -> *) x.
Amor (f x) =>
(f :$: x) -> (f :$: x) -> Maybe (Trans (f :$: x))
.-.? :: (f :$: x) -> (f :$: x) -> Maybe (Trans (f :$: x))
$c.-.? :: forall (f :: * -> *) x.
Amor (f x) =>
(f :$: x) -> (f :$: x) -> Maybe (Trans (f :$: x))
.+ :: (f :$: x) -> Trans (f :$: x) -> f :$: x
$c.+ :: forall (f :: * -> *) x.
Amor (f x) =>
(f :$: x) -> Trans (f :$: x) -> f :$: x
Amor, f :$: x
forall p. Amor p -> p -> Origin p
forall {f :: * -> *} {x}. Origin (f x) => Amor (f :$: x)
forall (f :: * -> *) x. Origin (f x) => f :$: x
origin :: f :$: x
$corigin :: forall (f :: * -> *) x. Origin (f x) => f :$: x
Origin) via (f x)

instance Show a => Show (Plain :$: a) where
  show :: (Plain :$: a) -> String
show (NoShow (Plain a
i)) = forall a. Show a => a -> String
show a
i

instance Show a => Show (IndexFrom n :$: a) where
  show :: (IndexFrom n :$: a) -> String
show (NoShow IndexFrom n a
i) = forall a. Show a => a -> String
show (forall (n :: Nat) a. IndexFrom n a -> a
fromIndex IndexFrom n a
i)

instance Show a => Show (Offset :$: a) where
  show :: (Offset :$: a) -> String
show (NoShow Offset a
i) = forall a. Show a => a -> String
show (forall a. Offset a -> a
fromOffset Offset a
i)

instance Num a => Num (Plain :$: a) where
  fromInteger :: Integer -> Plain :$: a
fromInteger Integer
n = forall (f :: * -> *) x. f x -> f :$: x
NoShow (forall a. a -> Plain a
Plain (forall a. Num a => Integer -> a
fromInteger Integer
n))
  + :: (Plain :$: a) -> (Plain :$: a) -> Plain :$: a
(+) = forall a. HasCallStack => a
undefined ; (-) = forall a. HasCallStack => a
undefined ; * :: (Plain :$: a) -> (Plain :$: a) -> Plain :$: a
(*) = forall a. HasCallStack => a
undefined ; abs :: (Plain :$: a) -> Plain :$: a
abs = forall a. HasCallStack => a
undefined ; signum :: (Plain :$: a) -> Plain :$: a
signum = forall a. HasCallStack => a
undefined

instance (Num a, Ord a, KnownNat n) => Num (IndexFrom n :$: a) where
  fromInteger :: Integer -> IndexFrom n :$: a
fromInteger Integer
n = forall (f :: * -> *) x. f x -> f :$: x
NoShow (forall (n :: Nat) a.
(HasCallStack, KnownNat n, Num a, Ord a) =>
a -> IndexFrom n a
indexFrom (forall a. Num a => Integer -> a
fromInteger Integer
n))
  + :: (IndexFrom n :$: a) -> (IndexFrom n :$: a) -> IndexFrom n :$: a
(+) = forall a. HasCallStack => a
undefined ; (-) = forall a. HasCallStack => a
undefined ; * :: (IndexFrom n :$: a) -> (IndexFrom n :$: a) -> IndexFrom n :$: a
(*) = forall a. HasCallStack => a
undefined ; abs :: (IndexFrom n :$: a) -> IndexFrom n :$: a
abs = forall a. HasCallStack => a
undefined ; signum :: (IndexFrom n :$: a) -> IndexFrom n :$: a
signum = forall a. HasCallStack => a
undefined

instance (Num a, Ord a) => Num (Offset :$: a) where
  fromInteger :: Integer -> Offset :$: a
fromInteger Integer
n = forall (f :: * -> *) x. f x -> f :$: x
NoShow (forall a. (HasCallStack, Num a, Ord a) => a -> Offset a
offset (forall a. Num a => Integer -> a
fromInteger Integer
n))
  + :: (Offset :$: a) -> (Offset :$: a) -> Offset :$: a
(+) = forall a. HasCallStack => a
undefined ; (-) = forall a. HasCallStack => a
undefined ; * :: (Offset :$: a) -> (Offset :$: a) -> Offset :$: a
(*) = forall a. HasCallStack => a
undefined ; abs :: (Offset :$: a) -> Offset :$: a
abs = forall a. HasCallStack => a
undefined ; signum :: (Offset :$: a) -> Offset :$: a
signum = forall a. HasCallStack => a
undefined

-- | Integers.
type Z = Plain :$: Int

-- | Natural numbers.
type N = IndexFrom 0 :$: Int

-- | Positive numbers.
type N' = IndexFrom 1 :$: Int