backprop-0.0.3.0: src/Data/Type/Util.hs
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
module Data.Type.Util (
Replicate
, unzipP
, zipP
, tagSum
, indexP
, vecToProd
, prodToVec'
, prodAlong
, lengthProd
, prodLength
, vecLength
, finIndex
, replLen
, replWit
, itraverse1_
, ifor1
, ifor1_
, for1
, for1_
) where
import Control.Applicative
import Data.Bifunctor
-- import Data.Kind
import Data.Monoid hiding (Sum)
import Data.Type.Conjunction
import Data.Type.Fin
import Data.Type.Index
import Data.Type.Length
import Data.Type.Nat
import Data.Type.Product
import Data.Type.Sum
import Data.Type.Vector
import Lens.Micro
import Type.Class.Higher
-- import Type.Class.Known
import Type.Class.Witness
-- import Type.Family.List
import Type.Family.Nat
-- | @'Replicate' n a@ is a list of @a@s repeated @n@ times.
--
-- >>> :kind! Replicate N3 Int
-- '[Int, Int, Int]
-- >>> :kind! Replicate N5 Double
-- '[Double, Double, Double, Double, Double]
type family Replicate (n :: N) (a :: k) = (as :: [k]) | as -> n where
Replicate 'Z a = '[]
Replicate ('S n) a = a ': Replicate n a
vecToProd
:: VecT n f a
-> Prod f (Replicate n a)
vecToProd = \case
ØV -> Ø
x :* xs -> x :< vecToProd xs
prodToVec'
:: Nat n
-> Prod f (Replicate n a)
-> VecT n f a
prodToVec' = \case
Z_ -> \case
Ø -> ØV
S_ n -> \case
x :< xs -> x :* prodToVec' n xs
prodAlong
:: VecT n f b
-> Prod f (Replicate n a)
-> VecT n f a
prodAlong = \case
ØV -> \case
Ø -> ØV
_ :* v -> \case
x :< xs -> x :* prodAlong v xs
finIndex
:: Fin n
-> Index (Replicate n a) a
finIndex = \case
FZ -> IZ
FS f -> IS (finIndex f)
traverse1_
:: (Applicative h, Traversable1 t)
=> (forall a. f a -> h ())
-> t f b
-> h ()
traverse1_ f = ($ pure ())
. appEndo
. getConst
. foldMap1 (\y -> Const (Endo (f y *>)))
itraverse1_
:: (Applicative h, IxFoldable1 i t)
=> (forall a. i b a -> f a -> h ())
-> t f b
-> h ()
itraverse1_ f = ($ pure ())
. appEndo
. getConst
. ifoldMap1 (\i y -> Const (Endo (f i y *>)))
for1
:: (Applicative h, Traversable1 t)
=> t f b
-> (forall a. f a -> h (g a))
-> h (t g b)
for1 x f = traverse1 f x
for1_
:: (Applicative h, Traversable1 t)
=> t f b
-> (forall a. f a -> h ())
-> h ()
for1_ x f = traverse1_ f x
ifor1
:: (Applicative h, IxTraversable1 i t)
=> t f b
-> (forall a. i b a -> f a -> h (g a))
-> h (t g b)
ifor1 x f = itraverse1 f x
ifor1_
:: (Applicative h, IxFoldable1 i t)
=> t f b
-> (forall a. i b a -> f a -> h ())
-> h ()
ifor1_ x f = itraverse1_ f x
zipP
:: Prod f as
-> Prod g as
-> Prod (f :&: g) as
zipP = \case
Ø -> \case
Ø -> Ø
x :< xs -> \case
y :< ys -> x :&: y :< zipP xs ys
unzipP
:: Prod (f :&: g) as
-> (Prod f as, Prod g as)
unzipP = \case
Ø -> (Ø, Ø)
(x :&: y) :< zs -> bimap (x :<) (y :<) (unzipP zs)
indexP :: Index as a -> Lens' (Prod g as) (g a)
indexP = \case
IZ -> \f -> \case
x :< xs -> (:< xs) <$> f x
IS i -> \f -> \case
x :< xs -> (x :<) <$> indexP i f xs
prodLength
:: Prod f as
-> Length as
prodLength = \case
Ø -> LZ
_ :< xs -> LS (prodLength xs)
vecLength
:: forall n f a. ()
=> VecT n f a
-> Nat n
vecLength = \case
ØV -> Z_
_ :* xs -> S_ (vecLength xs)
-- | Currently not used
tagSum
:: Prod f as
-> Sum g as
-> Sum (f :&: g) as
tagSum = \case
Ø -> \case
x :< xs -> \case
InL y -> InL (x :&: y)
InR ys -> InR (tagSum xs ys)
replWit
:: Nat n
-> Wit (c a)
-> Wit (Every c (Replicate n a))
replWit = \case
Z_ -> \case
Wit -> Wit
S_ n -> \case
c@Wit -> case replWit n c of
Wit -> Wit
replLen
:: forall n a. ()
=> Nat n
-> Length (Replicate n a)
replLen = \case
Z_ -> LZ
S_ n -> LS (replLen @_ @a n)
lengthProd
:: (forall a. f a)
-> Length as
-> Prod f as
lengthProd x = \case
LZ -> Ø
LS l -> x :< lengthProd x l