fun/recursion-schemes.bruijn


# uses Generic/Schemes.bruijn for ana/cata/para/etc.

:import std/Number .
:import std/Combinator .
:import std/Tuples .

# ===== #
# lists #
# ===== #

:import std/List/Church .
:import std/Monad/List .

# example list
list (+1) : ((+2) : {}(+3))

sum cata ([[[2 + 1]]] : (+0))

:test (list.sum =? (+6)) ([[1]])

length cata ([[[++1]]] : (+0))

:test (list.length =? (+3)) ([[1]])

tails para ([[[1 [[(4 : 1) : 0]]]]] : {}empty)

:test (list.tails) (list : (~list : (~(~list) : {}empty)))

splits para (lst : nil)
	lst [&[[[(empty : (3 : 2)) : (&[[(5 : 1) : 0]] <$> 1)]]]]
	nil {}(empty : empty)

…>>=… y [[[1 [[[(3 2) ++ (5 1 3)]]] empty]]]

perms foldr [[0 >>= splits >>= &[[{}(1 ++ {}3 ++ 0)]]]] {}empty

# ======= #
# numbers #
# ======= #

:import std/Number/Ternary .

fac para ((+1) : &[[0 ⋅ ++1]]) ⧗ Number → Number

fac hylo alg coalg
	coalg [=?0 [[0]] (0 : --0)]
	alg [[[2 ⋅ 1]]] : (+1)

# where
#  coalg 0 = Nil
#  coalg n = Cons n (n - 1)
#  alg Nil          = 1
#  alg (Cons n acc) = n * acc

# ==== #
# meta #
# ==== #

:import std/Meta .
:import std/Number/Conversion .

length cata (case-idx : case-app : case-abs)
	case-idx (add (+2)) ∘ unary→ternary
	case-app (add (+2)) ∘∘ add
	case-abs add (+2)

:test (length `[0]) ((+4))
:test (length `[[1 1]]) ((+12))

main [[0]]

:import std/List .
:import std/Number .

fac ^(list-y* (end : rest))
	end [[0 =? (+0) (+1) (0 ⋅ (^(~1) 0))]]
	rest y [[[[0 =? 2 (^1 --2) (1 !! ++2 0)]] : (1 ++0)]] (+1)

:import std/Imperative .

…;… …→…

# ([0 : (+1)] → (while (gets &[[not-eq? 1 (+0)]]) (get >>= &[[put (--1 : (mul 1 0))]])) → &[[0 [[0]]]])
fac i=1 ; (while (i≠0) n*=i;i-=1) ; return-n
	i=1 [0 : (+1)]
	i≠0 gets &[[1 ≠? (+0)]]
	n*=i;i-=1 get [[put (--1 : (1 ⋅ 0))]]
	return-n &[&[[0]]]