{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
module RecursionSchemes (
Fix(..)
, ListF(..)
, NatF(..)
, Nat
, RAlgebra
, ana
, cata
, para
, para'
, para''
, buildListF
, buildCoalg
, lengthAlg
, lengthListF
, lengthListF'
, fromNat
, toNat
, insert
, insert'
, toList
, idx0
, idx1
, idx2
, idx3
, idx4
) where
import Data.Bool (bool)
import Data.Function ((&))
newtype Fix f = Fix { forall (f :: * -> *). Fix f -> f (Fix f)
unFix :: f (Fix f) }
instance Show (f (Fix f)) => Show (Fix f) where
showsPrec :: Int -> Fix f -> ShowS
showsPrec Int
p (Fix f (Fix f)
f) = Int -> f (Fix f) -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
p f (Fix f)
f
instance Eq (f (Fix f)) => Eq (Fix f) where
Fix f (Fix f)
x == :: Fix f -> Fix f -> Bool
== Fix f (Fix f)
y = f (Fix f)
x f (Fix f) -> f (Fix f) -> Bool
forall a. Eq a => a -> a -> Bool
== f (Fix f)
y
Fix f (Fix f)
x /= :: Fix f -> Fix f -> Bool
/= Fix f (Fix f)
y = f (Fix f)
x f (Fix f) -> f (Fix f) -> Bool
forall a. Eq a => a -> a -> Bool
/= f (Fix f)
y
data ListF a r = NilF | ConsF a r deriving ((forall a b. (a -> b) -> ListF a a -> ListF a b)
-> (forall a b. a -> ListF a b -> ListF a a) -> Functor (ListF a)
forall a b. a -> ListF a b -> ListF a a
forall a b. (a -> b) -> ListF a a -> ListF a b
forall a a b. a -> ListF a b -> ListF a a
forall a a b. (a -> b) -> ListF a a -> ListF a 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 a b. (a -> b) -> ListF a a -> ListF a b
fmap :: forall a b. (a -> b) -> ListF a a -> ListF a b
$c<$ :: forall a a b. a -> ListF a b -> ListF a a
<$ :: forall a b. a -> ListF a b -> ListF a a
Functor, Int -> ListF a r -> ShowS
[ListF a r] -> ShowS
ListF a r -> String
(Int -> ListF a r -> ShowS)
-> (ListF a r -> String)
-> ([ListF a r] -> ShowS)
-> Show (ListF a r)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a r. (Show a, Show r) => Int -> ListF a r -> ShowS
forall a r. (Show a, Show r) => [ListF a r] -> ShowS
forall a r. (Show a, Show r) => ListF a r -> String
$cshowsPrec :: forall a r. (Show a, Show r) => Int -> ListF a r -> ShowS
showsPrec :: Int -> ListF a r -> ShowS
$cshow :: forall a r. (Show a, Show r) => ListF a r -> String
show :: ListF a r -> String
$cshowList :: forall a r. (Show a, Show r) => [ListF a r] -> ShowS
showList :: [ListF a r] -> ShowS
Show, ListF a r -> ListF a r -> Bool
(ListF a r -> ListF a r -> Bool)
-> (ListF a r -> ListF a r -> Bool) -> Eq (ListF a r)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall a r. (Eq a, Eq r) => ListF a r -> ListF a r -> Bool
$c== :: forall a r. (Eq a, Eq r) => ListF a r -> ListF a r -> Bool
== :: ListF a r -> ListF a r -> Bool
$c/= :: forall a r. (Eq a, Eq r) => ListF a r -> ListF a r -> Bool
/= :: ListF a r -> ListF a r -> Bool
Eq)
data NatF r = ZeroF | SuccF r deriving (Int -> NatF r -> ShowS
[NatF r] -> ShowS
NatF r -> String
(Int -> NatF r -> ShowS)
-> (NatF r -> String) -> ([NatF r] -> ShowS) -> Show (NatF r)
forall r. Show r => Int -> NatF r -> ShowS
forall r. Show r => [NatF r] -> ShowS
forall r. Show r => NatF r -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall r. Show r => Int -> NatF r -> ShowS
showsPrec :: Int -> NatF r -> ShowS
$cshow :: forall r. Show r => NatF r -> String
show :: NatF r -> String
$cshowList :: forall r. Show r => [NatF r] -> ShowS
showList :: [NatF r] -> ShowS
Show, (forall a b. (a -> b) -> NatF a -> NatF b)
-> (forall a b. a -> NatF b -> NatF a) -> Functor NatF
forall a b. a -> NatF b -> NatF a
forall a b. (a -> b) -> NatF a -> NatF 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) -> NatF a -> NatF b
fmap :: forall a b. (a -> b) -> NatF a -> NatF b
$c<$ :: forall a b. a -> NatF b -> NatF a
<$ :: forall a b. a -> NatF b -> NatF a
Functor)
type Nat = Fix NatF
type RAlgebra f a = Fix f -> f a -> a
ana :: Functor f => (a -> f a) -> a -> Fix f
ana :: forall (f :: * -> *) a. Functor f => (a -> f a) -> a -> Fix f
ana a -> f a
coalg = f (Fix f) -> Fix f
forall (f :: * -> *). f (Fix f) -> Fix f
Fix (f (Fix f) -> Fix f) -> (a -> f (Fix f)) -> a -> Fix f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Fix f) -> f a -> f (Fix f)
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> f a) -> a -> Fix f
forall (f :: * -> *) a. Functor f => (a -> f a) -> a -> Fix f
ana a -> f a
coalg) (f a -> f (Fix f)) -> (a -> f a) -> a -> f (Fix f)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> f a
coalg
cata :: Functor f => (f a -> a) -> Fix f -> a
cata :: forall (f :: * -> *) a. Functor f => (f a -> a) -> Fix f -> a
cata f a -> a
alg = f a -> a
alg (f a -> a) -> (Fix f -> f a) -> Fix f -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Fix f -> a) -> f (Fix f) -> f a
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((f a -> a) -> Fix f -> a
forall (f :: * -> *) a. Functor f => (f a -> a) -> Fix f -> a
cata f a -> a
alg) (f (Fix f) -> f a) -> (Fix f -> f (Fix f)) -> Fix f -> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fix f -> f (Fix f)
forall (f :: * -> *). Fix f -> f (Fix f)
unFix
para :: Functor f => RAlgebra f a -> Fix f -> a
para :: forall (f :: * -> *) a. Functor f => RAlgebra f a -> Fix f -> a
para RAlgebra f a
ralg Fix f
t = Fix f -> f (Fix f)
forall (f :: * -> *). Fix f -> f (Fix f)
unFix Fix f
t f (Fix f) -> (f (Fix f) -> f a) -> f a
forall a b. a -> (a -> b) -> b
& (Fix f -> a) -> f (Fix f) -> f a
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (RAlgebra f a -> Fix f -> a
forall (f :: * -> *) a. Functor f => RAlgebra f a -> Fix f -> a
para RAlgebra f a
ralg) f a -> (f a -> a) -> a
forall a b. a -> (a -> b) -> b
& RAlgebra f a
ralg Fix f
t
para' :: (a -> [a] -> b -> b) -> b -> [a] -> b
para' :: forall a b. (a -> [a] -> b -> b) -> b -> [a] -> b
para' a -> [a] -> b -> b
_ b
b [] = b
b
para' a -> [a] -> b -> b
op b
b (a
x:[a]
xs) = a -> [a] -> b -> b
op a
x [a]
xs ((a -> [a] -> b -> b) -> b -> [a] -> b
forall a b. (a -> [a] -> b -> b) -> b -> [a] -> b
para' a -> [a] -> b -> b
op b
b [a]
xs)
para'' :: (a -> [a] -> b -> b) -> b -> [a] -> b
para'' :: forall a b. (a -> [a] -> b -> b) -> b -> [a] -> b
para'' a -> [a] -> b -> b
op b
b [a]
xs = ([a], b) -> b
forall a b. (a, b) -> b
snd (([a], b) -> b) -> ([a], b) -> b
forall a b. (a -> b) -> a -> b
$ (a -> ([a], b) -> ([a], b)) -> ([a], b) -> [a] -> ([a], b)
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> ([a], b) -> ([a], b)
go ([], b
b) [a]
xs
where
go :: a -> ([a], b) -> ([a], b)
go a
y ([a]
ys, b
ys') = (a
ya -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
ys, a -> [a] -> b -> b
op a
y [a]
ys b
ys')
buildCoalg :: Int -> ListF Int Int
buildCoalg :: Int -> ListF Int Int
buildCoalg Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1 = ListF Int Int
forall a r. ListF a r
NilF
| Bool
otherwise = Int -> Int -> ListF Int Int
forall a r. a -> r -> ListF a r
ConsF Int
n (Int -> Int
forall a. Enum a => a -> a
pred Int
n)
buildListF :: Int -> Fix (ListF Int)
buildListF :: Int -> Fix (ListF Int)
buildListF = (Int -> ListF Int Int) -> Int -> Fix (ListF Int)
forall (f :: * -> *) a. Functor f => (a -> f a) -> a -> Fix f
ana Int -> ListF Int Int
buildCoalg
lengthAlg :: ListF a Int -> Int
lengthAlg :: forall a. ListF a Int -> Int
lengthAlg ListF a Int
ls = case ListF a Int
ls of
ListF a Int
NilF -> Int
0
ConsF a
_ Int
x -> Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
lengthListF :: Fix (ListF a) -> Int
lengthListF :: forall a. Fix (ListF a) -> Int
lengthListF = (ListF a Int -> Int) -> Fix (ListF a) -> Int
forall (f :: * -> *) a. Functor f => (f a -> a) -> Fix f -> a
cata ListF a Int -> Int
forall a. ListF a Int -> Int
lengthAlg
lengthListF' :: Fix (ListF a) -> Int
lengthListF' :: forall a. Fix (ListF a) -> Int
lengthListF' = RAlgebra (ListF a) Int -> Fix (ListF a) -> Int
forall (f :: * -> *) a. Functor f => RAlgebra f a -> Fix f -> a
para ((ListF a Int -> Int) -> RAlgebra (ListF a) Int
forall a b. a -> b -> a
const ListF a Int -> Int
forall a. ListF a Int -> Int
lengthAlg)
fromNat :: Nat -> Int
fromNat :: Nat -> Int
fromNat = (NatF Int -> Int) -> Nat -> Int
forall (f :: * -> *) a. Functor f => (f a -> a) -> Fix f -> a
cata NatF Int -> Int
forall {a}. Num a => NatF a -> a
alg where
alg :: NatF a -> a
alg NatF a
ZeroF = a
0
alg (SuccF a
n) = a
n a -> a -> a
forall a. Num a => a -> a -> a
+ a
1
toNat :: Int -> Nat
toNat :: Int -> Nat
toNat = (Int -> NatF Int) -> Int -> Nat
forall (f :: * -> *) a. Functor f => (a -> f a) -> a -> Fix f
ana Int -> NatF Int
forall {r}. (Ord r, Num r) => r -> NatF r
coalg where
coalg :: r -> NatF r
coalg r
n
| r
n r -> r -> Bool
forall a. Ord a => a -> a -> Bool
<= r
0 = NatF r
forall r. NatF r
ZeroF
| Bool
otherwise = r -> NatF r
forall r. r -> NatF r
SuccF (r
n r -> r -> r
forall a. Num a => a -> a -> a
- r
1)
insert :: Ord a => a -> [a] -> [a]
insert :: forall a. Ord a => a -> [a] -> [a]
insert a
e = ([a], [a]) -> [a]
forall a b. (a, b) -> b
snd (([a], [a]) -> [a]) -> ([a] -> ([a], [a])) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> ([a], [a]) -> ([a], [a])) -> ([a], [a]) -> [a] -> ([a], [a])
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> ([a], [a]) -> ([a], [a])
go ([], [a
e])
where
go :: a -> ([a], [a]) -> ([a], [a])
go a
y ([a]
ys, [a]
yse) = (a
ya -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
ys, [a] -> [a] -> Bool -> [a]
forall a. a -> a -> Bool -> a
bool (a
ya -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
yse) (a
ea -> [a] -> [a]
forall a. a -> [a] -> [a]
:a
ya -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
ys) (a
e a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
y))
insert' :: Ord a => a -> [a] -> [a]
insert' :: forall a. Ord a => a -> [a] -> [a]
insert' a
e = (a -> [a] -> [a] -> [a]) -> [a] -> [a] -> [a]
forall a b. (a -> [a] -> b -> b) -> b -> [a] -> b
para' a -> [a] -> [a] -> [a]
go [a
e]
where
go :: a -> [a] -> [a] -> [a]
go a
y [a]
ys [a]
yse = [a] -> [a] -> Bool -> [a]
forall a. a -> a -> Bool -> a
bool (a
ya -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
yse) (a
ea -> [a] -> [a]
forall a. a -> [a] -> [a]
:a
ya -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
ys) (a
e a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
y)
toList :: Fix (ListF a) -> [a]
toList :: forall a. Fix (ListF a) -> [a]
toList = (ListF a [a] -> [a]) -> Fix (ListF a) -> [a]
forall (f :: * -> *) a. Functor f => (f a -> a) -> Fix f -> a
cata ListF a [a] -> [a]
forall {a}. ListF a [a] -> [a]
alg
where alg :: ListF a [a] -> [a]
alg ListF a [a]
ls = case ListF a [a]
ls of
ListF a [a]
NilF -> []
ConsF a
a [a]
r -> a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
r
idx0 :: (Foldable t, Num b) => t a -> [b]
idx0 :: forall (t :: * -> *) b a. (Foldable t, Num b) => t a -> [b]
idx0 t a
as = t a -> (a -> (b -> [b]) -> b -> [b]) -> (b -> [b]) -> b -> [b]
forall (t :: * -> *) a b.
Foldable t =>
t a -> (a -> b -> b) -> b -> b
foldXs t a
as (\ a
_ b -> [b]
f b
m -> b
m b -> [b] -> [b]
forall a. a -> [a] -> [a]
: b -> [b]
f (b
m b -> b -> b
forall a. Num a => a -> a -> a
+ b
1)) ([b] -> b -> [b]
forall a b. a -> b -> a
const []) b
0
where
foldXs :: Foldable t => t a -> (a -> b -> b) -> b -> b
foldXs :: forall (t :: * -> *) a b.
Foldable t =>
t a -> (a -> b -> b) -> b -> b
foldXs t a
xs a -> b -> b
op b
b = (a -> b -> b) -> b -> t a -> b
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> b -> b
op b
b t a
xs
idx1 :: (Foldable t, Num b) => t a -> [b]
idx1 :: forall (t :: * -> *) b a. (Foldable t, Num b) => t a -> [b]
idx1 t a
xs = (a -> (b -> [b]) -> b -> [b]) -> (b -> [b]) -> t a -> b -> [b]
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\ a
_ b -> [b]
f b
m -> b
m b -> [b] -> [b]
forall a. a -> [a] -> [a]
: b -> [b]
f (b
m b -> b -> b
forall a. Num a => a -> a -> a
+ b
1)) ([b] -> b -> [b]
forall a b. a -> b -> a
const []) t a
xs b
0
idx2 :: [b] -> [Integer]
idx2 :: forall b. [b] -> [Integer]
idx2 = (Integer -> b -> Integer) -> [Integer] -> [b] -> [Integer]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Integer -> b -> Integer
forall a b. a -> b -> a
const [Integer
0..]
idx3 :: (Foldable t) => t a -> [Integer]
idx3 :: forall (t :: * -> *) a. Foldable t => t a -> [Integer]
idx3 t a
xs = (a -> ([Integer] -> [Integer]) -> [Integer] -> [Integer])
-> ([Integer] -> [Integer]) -> t a -> [Integer] -> [Integer]
forall a b. (a -> b -> b) -> b -> t a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\ a
_ [Integer] -> [Integer]
f (Integer
y:[Integer]
ys) -> Integer
y Integer -> [Integer] -> [Integer]
forall a. a -> [a] -> [a]
: [Integer] -> [Integer]
f [Integer]
ys) ([Integer] -> [Integer] -> [Integer]
forall a b. a -> b -> a
const []) t a
xs [Integer
0..]
idx4 :: [b] -> [Integer]
idx4 :: forall b. [b] -> [Integer]
idx4 = (Integer -> ([b] -> [Integer]) -> [b] -> [Integer])
-> ([b] -> [Integer]) -> [Integer] -> [b] -> [Integer]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Integer -> ([b] -> [Integer]) -> [b] -> [Integer]
forall {a} {a}. a -> ([a] -> [a]) -> [a] -> [a]
step ([Integer] -> [b] -> [Integer]
forall a b. a -> b -> a
const []) [Integer
0..]
where
step :: a -> ([a] -> [a]) -> [a] -> [a]
step a
_ [a] -> [a]
_ [] = []
step a
y [a] -> [a]
f (a
_:[a]
xs) = a
y a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a]
f [a]
xs