{-# LANGUAGE GADTs, TypeFamilies, TypeOperators, ScopedTypeVariables, CPP #-}
{-# LANGUAGE StandaloneDeriving, FlexibleInstances #-}
{-# LANGUAGE DefaultSignatures, FlexibleContexts, LambdaCase #-}
{-# OPTIONS_GHC -Wall -fenable-rewrite-rules #-}
module Data.MemoTrie
( HasTrie(..), (:->:)(..)
, domain, idTrie, (@.@)
, memo, memo2, memo3, mup
, inTrie, inTrie2, inTrie3
, trieGeneric, untrieGeneric, enumerateGeneric, Reg
, memoFix
) where
import Data.Function (fix)
import Data.Bits
import Data.Word
import Data.Int
#if !MIN_VERSION_base(4,8,0)
import Control.Applicative
#endif
import Control.Arrow (first,(&&&))
#if !MIN_VERSION_base(4,8,0)
import Data.Monoid
#endif
import Data.Function (on)
import GHC.Generics
import Control.Newtype.Generics
import Data.Void (Void)
infixr 0 :->:
class HasTrie a where
data (:->:) a :: * -> *
trie :: (a -> b) -> (a :->: b)
untrie :: (a :->: b) -> (a -> b)
enumerate :: (a :->: b) -> [(a,b)]
domain :: HasTrie a => [a]
domain :: [a]
domain = ((a, Any) -> a) -> [(a, Any)] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map (a, Any) -> a
forall a b. (a, b) -> a
fst ((a :->: Any) -> [(a, Any)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
enumerate ((a -> Any) -> a :->: Any
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (Any -> a -> Any
forall a b. a -> b -> a
const Any
forall a. a
oops)))
where
oops :: a
oops = [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"Data.MemoTrie.domain: range element evaluated."
instance (HasTrie a, Eq b) => Eq (a :->: b) where
== :: (a :->: b) -> (a :->: b) -> Bool
(==) = [b] -> [b] -> Bool
forall a. Eq a => a -> a -> Bool
(==) ([b] -> [b] -> Bool)
-> ((a :->: b) -> [b]) -> (a :->: b) -> (a :->: b) -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (((a, b) -> b) -> [(a, b)] -> [b]
forall a b. (a -> b) -> [a] -> [b]
map (a, b) -> b
forall a b. (a, b) -> b
snd ([(a, b)] -> [b]) -> ((a :->: b) -> [(a, b)]) -> (a :->: b) -> [b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a :->: b) -> [(a, b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
enumerate)
instance (HasTrie a, Show a, Show b) => Show (a :->: b) where
show :: (a :->: b) -> [Char]
show a :->: b
t = [Char]
"Trie: " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ [(a, b)] -> [Char]
forall a. Show a => a -> [Char]
show ((a :->: b) -> [(a, b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
enumerate a :->: b
t)
memo :: HasTrie t => (t -> a) -> (t -> a)
memo :: (t -> a) -> t -> a
memo = (t :->: a) -> t -> a
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie ((t :->: a) -> t -> a)
-> ((t -> a) -> t :->: a) -> (t -> a) -> t -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (t -> a) -> t :->: a
forall a b. HasTrie a => (a -> b) -> a :->: b
trie
memo2 :: (HasTrie s,HasTrie t) => (s -> t -> a) -> (s -> t -> a)
memo3 :: (HasTrie r,HasTrie s,HasTrie t) => (r -> s -> t -> a) -> (r -> s -> t -> a)
mup :: HasTrie t => (b -> c) -> (t -> b) -> (t -> c)
mup :: (b -> c) -> (t -> b) -> t -> c
mup b -> c
mem t -> b
f = (t -> c) -> t -> c
forall t a. HasTrie t => (t -> a) -> t -> a
memo (b -> c
mem (b -> c) -> (t -> b) -> t -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t -> b
f)
memo2 :: (s -> t -> a) -> s -> t -> a
memo2 = ((t -> a) -> t -> a) -> (s -> t -> a) -> s -> t -> a
forall t b c. HasTrie t => (b -> c) -> (t -> b) -> t -> c
mup (t -> a) -> t -> a
forall t a. HasTrie t => (t -> a) -> t -> a
memo
memo3 :: (r -> s -> t -> a) -> r -> s -> t -> a
memo3 = ((s -> t -> a) -> s -> t -> a)
-> (r -> s -> t -> a) -> r -> s -> t -> a
forall t b c. HasTrie t => (b -> c) -> (t -> b) -> t -> c
mup (s -> t -> a) -> s -> t -> a
forall s t a.
(HasTrie s, HasTrie t) =>
(s -> t -> a) -> s -> t -> a
memo2
memoFix :: HasTrie a => ((a -> b) -> (a -> b)) -> (a -> b)
memoFix :: ((a -> b) -> a -> b) -> a -> b
memoFix (a -> b) -> a -> b
h = ((a -> b) -> a -> b) -> a -> b
forall a. (a -> a) -> a
fix ((a -> b) -> a -> b
forall t a. HasTrie t => (t -> a) -> t -> a
memo ((a -> b) -> a -> b) -> ((a -> b) -> a -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> a -> b
h)
#if 0
memoFix h = fix (\ f' -> memo (h f'))
memoFix h = f'
where f' = memo (h f')
memoFix h = f'
where
f' = memo f
f = h f'
#endif
#if 0
fibF :: (Integer -> Integer) -> (Integer -> Integer)
fibF _ 0 = 1
fibF _ 1 = 1
fibF f n = f (n-1) + f (n-2)
fib :: Integer -> Integer
fib = fix fibF
fib' :: Integer -> Integer
fib' = memoFix fibF
#endif
inTrie :: (HasTrie a, HasTrie c) =>
((a -> b) -> (c -> d))
-> ((a :->: b) -> (c :->: d))
inTrie :: ((a -> b) -> c -> d) -> (a :->: b) -> c :->: d
inTrie = (a :->: b) -> a -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie ((a :->: b) -> a -> b)
-> ((c -> d) -> c :->: d)
-> ((a -> b) -> c -> d)
-> (a :->: b)
-> c :->: d
forall a' a b b'. (a' -> a) -> (b -> b') -> (a -> b) -> a' -> b'
~> (c -> d) -> c :->: d
forall a b. HasTrie a => (a -> b) -> a :->: b
trie
inTrie2 :: (HasTrie a, HasTrie c, HasTrie e) =>
((a -> b) -> (c -> d) -> (e -> f))
-> ((a :->: b) -> (c :->: d) -> (e :->: f))
inTrie2 :: ((a -> b) -> (c -> d) -> e -> f)
-> (a :->: b) -> (c :->: d) -> e :->: f
inTrie2 = (a :->: b) -> a -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie ((a :->: b) -> a -> b)
-> (((c -> d) -> e -> f) -> (c :->: d) -> e :->: f)
-> ((a -> b) -> (c -> d) -> e -> f)
-> (a :->: b)
-> (c :->: d)
-> e :->: f
forall a' a b b'. (a' -> a) -> (b -> b') -> (a -> b) -> a' -> b'
~> ((c -> d) -> e -> f) -> (c :->: d) -> e :->: f
forall a c b d.
(HasTrie a, HasTrie c) =>
((a -> b) -> c -> d) -> (a :->: b) -> c :->: d
inTrie
inTrie3 :: (HasTrie a, HasTrie c, HasTrie e, HasTrie g) =>
((a -> b) -> (c -> d) -> (e -> f) -> (g -> h))
-> ((a :->: b) -> (c :->: d) -> (e :->: f) -> (g :->: h))
inTrie3 :: ((a -> b) -> (c -> d) -> (e -> f) -> g -> h)
-> (a :->: b) -> (c :->: d) -> (e :->: f) -> g :->: h
inTrie3 = (a :->: b) -> a -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie ((a :->: b) -> a -> b)
-> (((c -> d) -> (e -> f) -> g -> h)
-> (c :->: d) -> (e :->: f) -> g :->: h)
-> ((a -> b) -> (c -> d) -> (e -> f) -> g -> h)
-> (a :->: b)
-> (c :->: d)
-> (e :->: f)
-> g :->: h
forall a' a b b'. (a' -> a) -> (b -> b') -> (a -> b) -> a' -> b'
~> ((c -> d) -> (e -> f) -> g -> h)
-> (c :->: d) -> (e :->: f) -> g :->: h
forall a c e b d f.
(HasTrie a, HasTrie c, HasTrie e) =>
((a -> b) -> (c -> d) -> e -> f)
-> (a :->: b) -> (c :->: d) -> e :->: f
inTrie2
instance HasTrie Void where
data Void :->: a = VoidTrie
trie :: (Void -> b) -> Void :->: b
trie Void -> b
_ = Void :->: b
forall a. Void :->: a
VoidTrie
untrie :: (Void :->: b) -> Void -> b
untrie Void :->: b
VoidTrie = \ Void
_ -> [Char] -> b
forall a. HasCallStack => [Char] -> a
error [Char]
"untrie VoidTrie"
enumerate :: (Void :->: b) -> [(Void, b)]
enumerate Void :->: b
VoidTrie = []
instance Newtype (Void :->: a) where
type O (Void :->: a) = ()
pack :: O (Void :->: a) -> Void :->: a
pack () = Void :->: a
forall a. Void :->: a
VoidTrie
unpack :: (Void :->: a) -> O (Void :->: a)
unpack Void :->: a
VoidTrie = ()
instance HasTrie () where
newtype () :->: a = UnitTrie a
trie :: (() -> b) -> () :->: b
trie () -> b
f = b -> () :->: b
forall a. a -> () :->: a
UnitTrie (() -> b
f ())
untrie :: (() :->: b) -> () -> b
untrie (UnitTrie a) = \ () -> b
a
enumerate :: (() :->: b) -> [((), b)]
enumerate (UnitTrie a) = [((),b
a)]
instance Newtype (() :->: a) where
type O (() :->: a) = a
pack :: O (() :->: a) -> () :->: a
pack O (() :->: a)
a = a -> () :->: a
forall a. a -> () :->: a
UnitTrie a
O (() :->: a)
a
unpack :: (() :->: a) -> O (() :->: a)
unpack (UnitTrie a) = a
O (() :->: a)
a
instance HasTrie Bool where
data Bool :->: x = BoolTrie x x
trie :: (Bool -> b) -> Bool :->: b
trie Bool -> b
f = b -> b -> Bool :->: b
forall x. x -> x -> Bool :->: x
BoolTrie (Bool -> b
f Bool
False) (Bool -> b
f Bool
True)
untrie :: (Bool :->: b) -> Bool -> b
untrie (BoolTrie f t) = b -> b -> Bool -> b
forall x. x -> x -> Bool -> x
if' b
f b
t
enumerate :: (Bool :->: b) -> [(Bool, b)]
enumerate (BoolTrie f t) = [(Bool
False,b
f),(Bool
True,b
t)]
instance Newtype (Bool :->: a) where
type O (Bool :->: a) = (a,a)
pack :: O (Bool :->: a) -> Bool :->: a
pack (a,a') = a -> a -> Bool :->: a
forall x. x -> x -> Bool :->: x
BoolTrie a
a a
a'
unpack :: (Bool :->: a) -> O (Bool :->: a)
unpack (BoolTrie a a') = (a
a,a
a')
if' :: x -> x -> Bool -> x
if' :: x -> x -> Bool -> x
if' x
t x
_ Bool
False = x
t
if' x
_ x
e Bool
True = x
e
instance HasTrie a => HasTrie (Maybe a) where
data (:->:) (Maybe a) b = MaybeTrie b (a :->: b)
trie :: (Maybe a -> b) -> Maybe a :->: b
trie Maybe a -> b
f = b -> (a :->: b) -> Maybe a :->: b
forall a b. b -> (a :->: b) -> Maybe a :->: b
MaybeTrie (Maybe a -> b
f Maybe a
forall a. Maybe a
Nothing) ((a -> b) -> a :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (Maybe a -> b
f (Maybe a -> b) -> (a -> Maybe a) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe a
forall a. a -> Maybe a
Just))
untrie :: (Maybe a :->: b) -> Maybe a -> b
untrie (MaybeTrie nothing_val a_trie) = b -> (a -> b) -> Maybe a -> b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe b
nothing_val ((a :->: b) -> a -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie a :->: b
a_trie)
enumerate :: (Maybe a :->: b) -> [(Maybe a, b)]
enumerate (MaybeTrie nothing_val a_trie) = (Maybe a
forall a. Maybe a
Nothing, b
nothing_val) (Maybe a, b) -> [(Maybe a, b)] -> [(Maybe a, b)]
forall a. a -> [a] -> [a]
: (a -> Maybe a) -> (a :->: b) -> [(Maybe a, b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' a -> Maybe a
forall a. a -> Maybe a
Just a :->: b
a_trie
instance Newtype (Maybe a :->: x) where
type O (Maybe a :->: x) = (x, a :->: x)
pack :: O (Maybe a :->: x) -> Maybe a :->: x
pack (a,f) = x -> (a :->: x) -> Maybe a :->: x
forall a b. b -> (a :->: b) -> Maybe a :->: b
MaybeTrie x
a a :->: x
f
unpack :: (Maybe a :->: x) -> O (Maybe a :->: x)
unpack (MaybeTrie a f) = (x
a,a :->: x
f)
instance (HasTrie a, HasTrie b) => HasTrie (Either a b) where
data (Either a b) :->: x = EitherTrie (a :->: x) (b :->: x)
trie :: (Either a b -> b) -> Either a b :->: b
trie Either a b -> b
f = (a :->: b) -> (b :->: b) -> Either a b :->: b
forall a b x. (a :->: x) -> (b :->: x) -> Either a b :->: x
EitherTrie ((a -> b) -> a :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (Either a b -> b
f (Either a b -> b) -> (a -> Either a b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Either a b
forall a b. a -> Either a b
Left)) ((b -> b) -> b :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (Either a b -> b
f (Either a b -> b) -> (b -> Either a b) -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Either a b
forall a b. b -> Either a b
Right))
untrie :: (Either a b :->: b) -> Either a b -> b
untrie (EitherTrie s t) = (a -> b) -> (b -> b) -> Either a b -> b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((a :->: b) -> a -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie a :->: b
s) ((b :->: b) -> b -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie b :->: b
t)
enumerate :: (Either a b :->: b) -> [(Either a b, b)]
enumerate (EitherTrie s t) = (a -> Either a b) -> (a :->: b) -> [(Either a b, b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' a -> Either a b
forall a b. a -> Either a b
Left a :->: b
s [(Either a b, b)] -> [(Either a b, b)] -> [(Either a b, b)]
forall a. [a] -> [a] -> [a]
`weave` (b -> Either a b) -> (b :->: b) -> [(Either a b, b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' b -> Either a b
forall a b. b -> Either a b
Right b :->: b
t
instance Newtype (Either a b :->: x) where
type O (Either a b :->: x) = (a :->: x, b :->: x)
pack :: O (Either a b :->: x) -> Either a b :->: x
pack (f,g) = (a :->: x) -> (b :->: x) -> Either a b :->: x
forall a b x. (a :->: x) -> (b :->: x) -> Either a b :->: x
EitherTrie a :->: x
f b :->: x
g
unpack :: (Either a b :->: x) -> O (Either a b :->: x)
unpack (EitherTrie f g) = (a :->: x
f,b :->: x
g)
enum' :: (HasTrie a) => (a -> a') -> (a :->: b) -> [(a', b)]
enum' :: (a -> a') -> (a :->: b) -> [(a', b)]
enum' a -> a'
f = (((a, b) -> (a', b)) -> [(a, b)] -> [(a', b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap(((a, b) -> (a', b)) -> [(a, b)] -> [(a', b)])
-> ((a -> a') -> (a, b) -> (a', b))
-> (a -> a')
-> [(a, b)]
-> [(a', b)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(a -> a') -> (a, b) -> (a', b)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first) a -> a'
f ([(a, b)] -> [(a', b)])
-> ((a :->: b) -> [(a, b)]) -> (a :->: b) -> [(a', b)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a :->: b) -> [(a, b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
enumerate
weave :: [a] -> [a] -> [a]
[] weave :: [a] -> [a] -> [a]
`weave` [a]
as = [a]
as
[a]
as `weave` [] = [a]
as
(a
a:[a]
as) `weave` [a]
bs = a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: ([a]
bs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
`weave` [a]
as)
instance (HasTrie a, HasTrie b) => HasTrie (a,b) where
newtype (a,b) :->: x = PairTrie (a :->: (b :->: x))
trie :: ((a, b) -> b) -> (a, b) :->: b
trie (a, b) -> b
f = (a :->: (b :->: b)) -> (a, b) :->: b
forall a b x. (a :->: (b :->: x)) -> (a, b) :->: x
PairTrie ((a -> b :->: b) -> a :->: (b :->: b)
forall a b. HasTrie a => (a -> b) -> a :->: b
trie ((b -> b) -> b :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie ((b -> b) -> b :->: b) -> (a -> b -> b) -> a -> b :->: b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, b) -> b) -> a -> b -> b
forall a b c. ((a, b) -> c) -> a -> b -> c
curry (a, b) -> b
f))
untrie :: ((a, b) :->: b) -> (a, b) -> b
untrie (PairTrie t) = (a -> b -> b) -> (a, b) -> b
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((b :->: b) -> b -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie ((b :->: b) -> b -> b) -> (a -> b :->: b) -> a -> b -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a :->: (b :->: b)) -> a -> b :->: b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie a :->: (b :->: b)
t)
enumerate :: ((a, b) :->: b) -> [((a, b), b)]
enumerate (PairTrie tt) =
[ ((a
a,b
b),b
x) | (a
a,b :->: b
t) <- (a :->: (b :->: b)) -> [(a, b :->: b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
enumerate a :->: (b :->: b)
tt , (b
b,b
x) <- (b :->: b) -> [(b, b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
enumerate b :->: b
t ]
instance Newtype ((a,b) :->: x) where
type O ((a,b) :->: x) = a :->: b :->: x
pack :: O ((a, b) :->: x) -> (a, b) :->: x
pack O ((a, b) :->: x)
abx = (a :->: (b :->: x)) -> (a, b) :->: x
forall a b x. (a :->: (b :->: x)) -> (a, b) :->: x
PairTrie O ((a, b) :->: x)
a :->: (b :->: x)
abx
unpack :: ((a, b) :->: x) -> O ((a, b) :->: x)
unpack (PairTrie abx) = O ((a, b) :->: x)
a :->: (b :->: x)
abx
instance (HasTrie a, HasTrie b, HasTrie c) => HasTrie (a,b,c) where
newtype (a,b,c) :->: x = TripleTrie (((a,b),c) :->: x)
trie :: ((a, b, c) -> b) -> (a, b, c) :->: b
trie (a, b, c) -> b
f = (((a, b), c) :->: b) -> (a, b, c) :->: b
forall a b c x. (((a, b), c) :->: x) -> (a, b, c) :->: x
TripleTrie ((((a, b), c) -> b) -> ((a, b), c) :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie ((a, b, c) -> b
f ((a, b, c) -> b) -> (((a, b), c) -> (a, b, c)) -> ((a, b), c) -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, b), c) -> (a, b, c)
forall a b c. ((a, b), c) -> (a, b, c)
trip))
untrie :: ((a, b, c) :->: b) -> (a, b, c) -> b
untrie (TripleTrie t) = (((a, b), c) :->: b) -> ((a, b), c) -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie ((a, b), c) :->: b
t (((a, b), c) -> b) -> ((a, b, c) -> ((a, b), c)) -> (a, b, c) -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, b, c) -> ((a, b), c)
forall a b c. (a, b, c) -> ((a, b), c)
detrip
enumerate :: ((a, b, c) :->: b) -> [((a, b, c), b)]
enumerate (TripleTrie t) = (((a, b), c) -> (a, b, c))
-> (((a, b), c) :->: b) -> [((a, b, c), b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' ((a, b), c) -> (a, b, c)
forall a b c. ((a, b), c) -> (a, b, c)
trip ((a, b), c) :->: b
t
trip :: ((a,b),c) -> (a,b,c)
trip :: ((a, b), c) -> (a, b, c)
trip ((a
a,b
b),c
c) = (a
a,b
b,c
c)
detrip :: (a,b,c) -> ((a,b),c)
detrip :: (a, b, c) -> ((a, b), c)
detrip (a
a,b
b,c
c) = ((a
a,b
b),c
c)
instance HasTrie x => HasTrie [x] where
newtype [x] :->: a = ListTrie (Either () (x,[x]) :->: a)
trie :: ([x] -> b) -> [x] :->: b
trie [x] -> b
f = (Either () (x, [x]) :->: b) -> [x] :->: b
forall x a. (Either () (x, [x]) :->: a) -> [x] :->: a
ListTrie ((Either () (x, [x]) -> b) -> Either () (x, [x]) :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie ([x] -> b
f ([x] -> b)
-> (Either () (x, [x]) -> [x]) -> Either () (x, [x]) -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either () (x, [x]) -> [x]
forall x. Either () (x, [x]) -> [x]
list))
untrie :: ([x] :->: b) -> [x] -> b
untrie (ListTrie t) = (Either () (x, [x]) :->: b) -> Either () (x, [x]) -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie Either () (x, [x]) :->: b
t (Either () (x, [x]) -> b)
-> ([x] -> Either () (x, [x])) -> [x] -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [x] -> Either () (x, [x])
forall x. [x] -> Either () (x, [x])
delist
enumerate :: ([x] :->: b) -> [([x], b)]
enumerate (ListTrie t) = (Either () (x, [x]) -> [x])
-> (Either () (x, [x]) :->: b) -> [([x], b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' Either () (x, [x]) -> [x]
forall x. Either () (x, [x]) -> [x]
list Either () (x, [x]) :->: b
t
list :: Either () (x,[x]) -> [x]
list :: Either () (x, [x]) -> [x]
list = (() -> [x]) -> ((x, [x]) -> [x]) -> Either () (x, [x]) -> [x]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ([x] -> () -> [x]
forall a b. a -> b -> a
const []) ((x -> [x] -> [x]) -> (x, [x]) -> [x]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:))
delist :: [x] -> Either () (x,[x])
delist :: [x] -> Either () (x, [x])
delist [] = () -> Either () (x, [x])
forall a b. a -> Either a b
Left ()
delist (x
x:[x]
xs) = (x, [x]) -> Either () (x, [x])
forall a b. b -> Either a b
Right (x
x,[x]
xs)
#define WordInstance(Type,TrieType)\
instance HasTrie Type where \
newtype Type :->: a = TrieType ([Bool] :->: a);\
trie f = TrieType (trie (f . unbits));\
untrie (TrieType t) = untrie t . bits;\
enumerate (TrieType t) = enum' unbits t
WordInstance(Word,WordTrie)
WordInstance(Word8,Word8Trie)
WordInstance(Word16,Word16Trie)
WordInstance(Word32,Word32Trie)
WordInstance(Word64,Word64Trie)
bits :: (Num t, Bits t) => t -> [Bool]
bits :: t -> [Bool]
bits t
0 = []
bits t
x = t -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit t
x Int
0 Bool -> [Bool] -> [Bool]
forall a. a -> [a] -> [a]
: t -> [Bool]
forall t. (Num t, Bits t) => t -> [Bool]
bits (t -> Int -> t
forall a. Bits a => a -> Int -> a
shiftR t
x Int
1)
unbit :: Num t => Bool -> t
unbit :: Bool -> t
unbit Bool
False = t
0
unbit Bool
True = t
1
unbits :: (Num t, Bits t) => [Bool] -> t
unbits :: [Bool] -> t
unbits [] = t
0
unbits (Bool
x:[Bool]
xs) = Bool -> t
forall t. Num t => Bool -> t
unbit Bool
x t -> t -> t
forall a. Bits a => a -> a -> a
.|. t -> Int -> t
forall a. Bits a => a -> Int -> a
shiftL ([Bool] -> t
forall t. (Num t, Bits t) => [Bool] -> t
unbits [Bool]
xs) Int
1
instance HasTrie Char where
newtype Char :->: a = CharTrie (Int :->: a)
untrie :: (Char :->: b) -> Char -> b
untrie (CharTrie t) Char
n = (Int :->: b) -> Int -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie Int :->: b
t (Char -> Int
forall a. Enum a => a -> Int
fromEnum Char
n)
trie :: (Char -> b) -> Char :->: b
trie Char -> b
f = (Int :->: b) -> Char :->: b
forall a. (Int :->: a) -> Char :->: a
CharTrie ((Int -> b) -> Int :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (Char -> b
f (Char -> b) -> (Int -> Char) -> Int -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Char
forall a. Enum a => Int -> a
toEnum))
enumerate :: (Char :->: b) -> [(Char, b)]
enumerate (CharTrie t) = (Int -> Char) -> (Int :->: b) -> [(Char, b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' Int -> Char
forall a. Enum a => Int -> a
toEnum Int :->: b
t
#define IntInstance(IntType,WordType,TrieType) \
instance HasTrie IntType where \
newtype IntType :->: a = TrieType (WordType :->: a); \
untrie (TrieType t) n = untrie t (fromIntegral n); \
trie f = TrieType (trie (f . fromIntegral)); \
enumerate (TrieType t) = enum' fromIntegral t
IntInstance(Int,Word,IntTrie)
IntInstance(Int8,Word8,Int8Trie)
IntInstance(Int16,Word16,Int16Trie)
IntInstance(Int32,Word32,Int32Trie)
IntInstance(Int64,Word64,Int64Trie)
instance HasTrie Integer where
newtype Integer :->: a = IntegerTrie ((Bool,[Bool]) :->: a)
trie :: (Integer -> b) -> Integer :->: b
trie Integer -> b
f = ((Bool, [Bool]) :->: b) -> Integer :->: b
forall a. ((Bool, [Bool]) :->: a) -> Integer :->: a
IntegerTrie (((Bool, [Bool]) -> b) -> (Bool, [Bool]) :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (Integer -> b
f (Integer -> b)
-> ((Bool, [Bool]) -> Integer) -> (Bool, [Bool]) -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool, [Bool]) -> Integer
forall n. (Num n, Bits n) => (Bool, [Bool]) -> n
unbitsZ))
untrie :: (Integer :->: b) -> Integer -> b
untrie (IntegerTrie t) = ((Bool, [Bool]) :->: b) -> (Bool, [Bool]) -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie (Bool, [Bool]) :->: b
t ((Bool, [Bool]) -> b)
-> (Integer -> (Bool, [Bool])) -> Integer -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> (Bool, [Bool])
forall n. (Num n, Ord n, Bits n) => n -> (Bool, [Bool])
bitsZ
enumerate :: (Integer :->: b) -> [(Integer, b)]
enumerate (IntegerTrie t) = ((Bool, [Bool]) -> Integer)
-> ((Bool, [Bool]) :->: b) -> [(Integer, b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' (Bool, [Bool]) -> Integer
forall n. (Num n, Bits n) => (Bool, [Bool]) -> n
unbitsZ (Bool, [Bool]) :->: b
t
unbitsZ :: (Num n, Bits n) => (Bool,[Bool]) -> n
unbitsZ :: (Bool, [Bool]) -> n
unbitsZ (Bool
positive,[Bool]
bs) = n -> n
sig ([Bool] -> n
forall t. (Num t, Bits t) => [Bool] -> t
unbits [Bool]
bs)
where
sig :: n -> n
sig | Bool
positive = n -> n
forall a. a -> a
id
| Bool
otherwise = n -> n
forall a. Num a => a -> a
negate
bitsZ :: (Num n, Ord n, Bits n) => n -> (Bool,[Bool])
bitsZ :: n -> (Bool, [Bool])
bitsZ = (n -> n -> Bool
forall a. Ord a => a -> a -> Bool
>= n
0) (n -> Bool) -> (n -> [Bool]) -> n -> (Bool, [Bool])
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& (n -> [Bool]
forall t. (Num t, Bits t) => t -> [Bool]
bits (n -> [Bool]) -> (n -> n) -> n -> [Bool]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. n -> n
forall a. Num a => a -> a
abs)
instance (HasTrie a, Monoid b) => Monoid (a :->: b) where
mempty :: a :->: b
mempty = (a -> b) -> a :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie a -> b
forall a. Monoid a => a
mempty
#if !MIN_VERSION_base(4,11,0)
mappend = inTrie2 mappend
#else
instance (HasTrie a, Semigroup b) => Semigroup (a :->: b) where
<> :: (a :->: b) -> (a :->: b) -> a :->: b
(<>) = ((a -> b) -> (a -> b) -> a -> b)
-> (a :->: b) -> (a :->: b) -> a :->: b
forall a c e b d f.
(HasTrie a, HasTrie c, HasTrie e) =>
((a -> b) -> (c -> d) -> e -> f)
-> (a :->: b) -> (c :->: d) -> e :->: f
inTrie2 (a -> b) -> (a -> b) -> a -> b
forall a. Semigroup a => a -> a -> a
(<>)
#endif
instance HasTrie a => Functor ((:->:) a) where
fmap :: (a -> b) -> (a :->: a) -> a :->: b
fmap a -> b
f = ((a -> a) -> a -> b) -> (a :->: a) -> a :->: b
forall a c b d.
(HasTrie a, HasTrie c) =>
((a -> b) -> c -> d) -> (a :->: b) -> c :->: d
inTrie ((a -> b) -> (a -> a) -> a -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f)
instance HasTrie a => Applicative ((:->:) a) where
pure :: a -> a :->: a
pure a
b = (a -> a) -> a :->: a
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (a -> a -> a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
b)
<*> :: (a :->: (a -> b)) -> (a :->: a) -> a :->: b
(<*>) = ((a -> a -> b) -> (a -> a) -> a -> b)
-> (a :->: (a -> b)) -> (a :->: a) -> a :->: b
forall a c e b d f.
(HasTrie a, HasTrie c, HasTrie e) =>
((a -> b) -> (c -> d) -> e -> f)
-> (a :->: b) -> (c :->: d) -> e :->: f
inTrie2 (a -> a -> b) -> (a -> a) -> a -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
instance HasTrie a => Monad ((:->:) a) where
return :: a -> a :->: a
return a
a = (a -> a) -> a :->: a
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (a -> a -> a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a)
a :->: a
u >>= :: (a :->: a) -> (a -> a :->: b) -> a :->: b
>>= a -> a :->: b
k = (a -> b) -> a :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie ((a :->: a) -> a -> a
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie a :->: a
u (a -> a) -> (a -> a -> b) -> a -> b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a :->: b) -> a -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie ((a :->: b) -> a -> b) -> (a -> a :->: b) -> a -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a :->: b
k)
idTrie :: HasTrie a => a :->: a
idTrie :: a :->: a
idTrie = (a -> a) -> a :->: a
forall a b. HasTrie a => (a -> b) -> a :->: b
trie a -> a
forall a. a -> a
id
infixr 9 @.@
(@.@) :: (HasTrie a, HasTrie b) =>
(b :->: c) -> (a :->: b) -> (a :->: c)
@.@ :: (b :->: c) -> (a :->: b) -> a :->: c
(@.@) = ((b -> c) -> (a -> b) -> a -> c)
-> (b :->: c) -> (a :->: b) -> a :->: c
forall a c e b d f.
(HasTrie a, HasTrie c, HasTrie e) =>
((a -> b) -> (c -> d) -> e -> f)
-> (a :->: b) -> (c :->: d) -> e :->: f
inTrie2 (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)
(~>) :: (a' -> a) -> (b -> b') -> ((a -> b) -> (a' -> b'))
a' -> a
g ~> :: (a' -> a) -> (b -> b') -> (a -> b) -> a' -> b'
~> b -> b'
f = (b -> b'
f (b -> b') -> (a' -> b) -> a' -> b'
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((a' -> b) -> a' -> b')
-> ((a -> b) -> a' -> b) -> (a -> b) -> a' -> b'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a -> b) -> (a' -> a) -> a' -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a' -> a
g)
instance HasTrie (V1 x) where
data (V1 x :->: b) = V1Trie
trie :: (V1 x -> b) -> V1 x :->: b
trie V1 x -> b
_ = V1 x :->: b
forall x b. V1 x :->: b
V1Trie
untrie :: (V1 x :->: b) -> V1 x -> b
untrie V1 x :->: b
V1Trie = \ V1 x
_ -> [Char] -> b
forall a. HasCallStack => [Char] -> a
error [Char]
"untrie V1Trie"
enumerate :: (V1 x :->: b) -> [(V1 x, b)]
enumerate V1 x :->: b
V1Trie = []
instance HasTrie (U1 x) where
data (U1 x :->: b) = U1Trie b
trie :: (U1 x -> b) -> U1 x :->: b
trie U1 x -> b
f = b -> U1 x :->: b
forall x b. b -> U1 x :->: b
U1Trie (U1 x -> b
f U1 x
forall k (p :: k). U1 p
U1)
untrie :: (U1 x :->: b) -> U1 x -> b
untrie (U1Trie b) = \U1 x
U1 -> b
b
enumerate :: (U1 x :->: b) -> [(U1 x, b)]
enumerate (U1Trie b) = [(U1 x
forall k (p :: k). U1 p
U1, b
b)]
instance (HasTrie (f x), HasTrie (g x)) => HasTrie ((f :+: g) x) where
newtype ((f :+: g) x :->: b) = EitherTrie1 (Either (f x) (g x) :->: b)
trie :: ((:+:) f g x -> b) -> (:+:) f g x :->: b
trie (:+:) f g x -> b
f = (Either (f x) (g x) :->: b) -> (:+:) f g x :->: b
forall (f :: * -> *) (g :: * -> *) x b.
(Either (f x) (g x) :->: b) -> (:+:) f g x :->: b
EitherTrie1 ((Either (f x) (g x) -> b) -> Either (f x) (g x) :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie ((:+:) f g x -> b
f ((:+:) f g x -> b)
-> (Either (f x) (g x) -> (:+:) f g x) -> Either (f x) (g x) -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either (f x) (g x) -> (:+:) f g x
forall (f :: * -> *) a (g :: * -> *).
Either (f a) (g a) -> (:+:) f g a
liftSum))
untrie :: ((:+:) f g x :->: b) -> (:+:) f g x -> b
untrie (EitherTrie1 t) = ((Either (f x) (g x) :->: b) -> Either (f x) (g x) -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie Either (f x) (g x) :->: b
t) (Either (f x) (g x) -> b)
-> ((:+:) f g x -> Either (f x) (g x)) -> (:+:) f g x -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:+:) f g x -> Either (f x) (g x)
forall (f :: * -> *) (g :: * -> *) a.
(:+:) f g a -> Either (f a) (g a)
dropSum
enumerate :: ((:+:) f g x :->: b) -> [((:+:) f g x, b)]
enumerate (EitherTrie1 t) = (Either (f x) (g x) -> (:+:) f g x)
-> (Either (f x) (g x) :->: b) -> [((:+:) f g x, b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' Either (f x) (g x) -> (:+:) f g x
forall (f :: * -> *) a (g :: * -> *).
Either (f a) (g a) -> (:+:) f g a
liftSum Either (f x) (g x) :->: b
t
instance (HasTrie (f x), HasTrie (g x)) => HasTrie ((f :*: g) x) where
newtype ((f :*: g) x :->: b) = PairTrie1 ((f x, g x) :->: b)
trie :: ((:*:) f g x -> b) -> (:*:) f g x :->: b
trie (:*:) f g x -> b
f = ((f x, g x) :->: b) -> (:*:) f g x :->: b
forall (f :: * -> *) (g :: * -> *) x b.
((f x, g x) :->: b) -> (:*:) f g x :->: b
PairTrie1 (((f x, g x) -> b) -> (f x, g x) :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie ((:*:) f g x -> b
f ((:*:) f g x -> b)
-> ((f x, g x) -> (:*:) f g x) -> (f x, g x) -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f x, g x) -> (:*:) f g x
forall (f :: * -> *) a (g :: * -> *). (f a, g a) -> (:*:) f g a
liftProduct))
untrie :: ((:*:) f g x :->: b) -> (:*:) f g x -> b
untrie (PairTrie1 t) = (((f x, g x) :->: b) -> (f x, g x) -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie (f x, g x) :->: b
t) ((f x, g x) -> b)
-> ((:*:) f g x -> (f x, g x)) -> (:*:) f g x -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:*:) f g x -> (f x, g x)
forall (f :: * -> *) (g :: * -> *) a. (:*:) f g a -> (f a, g a)
dropProduct
enumerate :: ((:*:) f g x :->: b) -> [((:*:) f g x, b)]
enumerate (PairTrie1 t) = ((f x, g x) -> (:*:) f g x)
-> ((f x, g x) :->: b) -> [((:*:) f g x, b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' (f x, g x) -> (:*:) f g x
forall (f :: * -> *) a (g :: * -> *). (f a, g a) -> (:*:) f g a
liftProduct (f x, g x) :->: b
t
instance (HasTrie a) => HasTrie (K1 i a x) where
data (K1 i a x :->: b) = K1Trie (a :->: b)
trie :: (K1 i a x -> b) -> K1 i a x :->: b
trie K1 i a x -> b
f = (a :->: b) -> K1 i a x :->: b
forall i a x b. (a :->: b) -> K1 i a x :->: b
K1Trie ((a -> b) -> a :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (K1 i a x -> b
f (K1 i a x -> b) -> (a -> K1 i a x) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> K1 i a x
forall k i c (p :: k). c -> K1 i c p
K1))
untrie :: (K1 i a x :->: b) -> K1 i a x -> b
untrie (K1Trie t) = \(K1 a
a) -> ((a :->: b) -> a -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie a :->: b
t) a
a
enumerate :: (K1 i a x :->: b) -> [(K1 i a x, b)]
enumerate (K1Trie t) = (a -> K1 i a x) -> (a :->: b) -> [(K1 i a x, b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' a -> K1 i a x
forall k i c (p :: k). c -> K1 i c p
K1 a :->: b
t
instance (HasTrie (f x)) => HasTrie (M1 i t f x) where
data (M1 i t f x :->: b) = M1Trie (f x :->: b)
trie :: (M1 i t f x -> b) -> M1 i t f x :->: b
trie M1 i t f x -> b
f = (f x :->: b) -> M1 i t f x :->: b
forall i (t :: Meta) (f :: * -> *) x b.
(f x :->: b) -> M1 i t f x :->: b
M1Trie ((f x -> b) -> f x :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (M1 i t f x -> b
f (M1 i t f x -> b) -> (f x -> M1 i t f x) -> f x -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f x -> M1 i t f x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1))
untrie :: (M1 i t f x :->: b) -> M1 i t f x -> b
untrie (M1Trie t) = \(M1 f x
a) -> ((f x :->: b) -> f x -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie f x :->: b
t) f x
a
enumerate :: (M1 i t f x :->: b) -> [(M1 i t f x, b)]
enumerate (M1Trie t) = (f x -> M1 i t f x) -> (f x :->: b) -> [(M1 i t f x, b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' f x -> M1 i t f x
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 f x :->: b
t
type Reg a = Rep a ()
trieGeneric :: (Generic a, HasTrie (Reg a))
=> ((Reg a :->: b) -> (a :->: b))
-> (a -> b)
-> (a :->: b)
trieGeneric :: ((Reg a :->: b) -> a :->: b) -> (a -> b) -> a :->: b
trieGeneric (Reg a :->: b) -> a :->: b
theConstructor a -> b
f = (Reg a :->: b) -> a :->: b
theConstructor ((Reg a -> b) -> Reg a :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
trie (a -> b
f (a -> b) -> (Reg a -> a) -> Reg a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reg a -> a
forall a x. Generic a => Rep a x -> a
to))
{-# INLINEABLE trieGeneric #-}
untrieGeneric :: (Generic a, HasTrie (Reg a))
=> ((a :->: b) -> (Reg a :->: b))
-> (a :->: b)
-> (a -> b)
untrieGeneric :: ((a :->: b) -> Reg a :->: b) -> (a :->: b) -> a -> b
untrieGeneric (a :->: b) -> Reg a :->: b
theDestructor a :->: b
t = \a
a -> ((Reg a :->: b) -> Reg a -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
untrie ((a :->: b) -> Reg a :->: b
theDestructor a :->: b
t)) (a -> Reg a
forall a x. Generic a => a -> Rep a x
from a
a)
{-# INLINEABLE untrieGeneric #-}
enumerateGeneric :: (Generic a, HasTrie (Reg a))
=> ((a :->: b) -> (Reg a :->: b))
-> (a :->: b)
-> [(a, b)]
enumerateGeneric :: ((a :->: b) -> Reg a :->: b) -> (a :->: b) -> [(a, b)]
enumerateGeneric (a :->: b) -> Reg a :->: b
theDestructor a :->: b
t = (Reg a -> a) -> (Reg a :->: b) -> [(a, b)]
forall a a' b. HasTrie a => (a -> a') -> (a :->: b) -> [(a', b)]
enum' Reg a -> a
forall a x. Generic a => Rep a x -> a
to ((a :->: b) -> Reg a :->: b
theDestructor a :->: b
t)
{-# INLINEABLE enumerateGeneric #-}
dropProduct :: (f :*: g) a -> (f a, g a)
dropProduct :: (:*:) f g a -> (f a, g a)
dropProduct (f a
a :*: g a
b) = (f a
a, g a
b)
{-# INLINEABLE dropProduct #-}
liftProduct :: (f a, g a) -> (f :*: g) a
liftProduct :: (f a, g a) -> (:*:) f g a
liftProduct (f a
a, g a
b) = (f a
a f a -> g a -> (:*:) f g a
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g a
b)
{-# INLINEABLE liftProduct #-}
dropSum :: (f :+: g) a -> Either (f a) (g a)
dropSum :: (:+:) f g a -> Either (f a) (g a)
dropSum (:+:) f g a
s = case (:+:) f g a
s of
L1 f a
x -> f a -> Either (f a) (g a)
forall a b. a -> Either a b
Left f a
x
R1 g a
x -> g a -> Either (f a) (g a)
forall a b. b -> Either a b
Right g a
x
{-# INLINEABLE dropSum #-}
liftSum :: Either (f a) (g a) -> (f :+: g) a
liftSum :: Either (f a) (g a) -> (:+:) f g a
liftSum = (f a -> (:+:) f g a)
-> (g a -> (:+:) f g a) -> Either (f a) (g a) -> (:+:) f g a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either f a -> (:+:) f g a
forall k (f :: k -> *) (g :: k -> *) (p :: k). f p -> (:+:) f g p
L1 g a -> (:+:) f g a
forall k (f :: k -> *) (g :: k -> *) (p :: k). g p -> (:+:) f g p
R1
{-# INLINEABLE liftSum #-}