import { constant } from 'fp-ts/lib/function' ; import { Functor , Functor1 , Functor2 , Functor3 } from 'fp-ts/lib/Functor' ; import { Type , Type2 , Type3 , URIS , URIS2 , URIS3 } from 'fp-ts/lib/HKT' ; import { match } from './match' ; import { Algebra , Fix , unfix } from './Fix' ; import { functorNat , Nat , NatF , succ , zero } from './Nat' ; export function cata < F extends URIS3 > ( F ) ; export function cata < F extends URIS2 > ( F ) ; export function cata < F extends URIS > ( F ) ; export function cata < F > ( F ) ; export function cata < F > ( F ) { return < A > ( algebra ) => function self ( term ) : A { return algebra ( F . map ( unfix ( term ) , self ) ) ; } ; } const idAlg = ( n ) : number => match ( n . _tag ) ( { Zero : constant ( 0 ) , Succ : ( ) => 1 + n . value , } ) ; const toNumber = ( n ) : number => cata ( functorNat ) ( idAlg ) ( n ) ; const plusAlg = ( a ) => ( n ) : Nat => match ( n . _tag ) ( { Zero : constant ( a ) , Succ : ( ) => succ ( n . value ) , } ) ; const plus = ( a ) => ( b ) : Nat => cata ( functorNat ) ( plusAlg ( a ) ) ( b ) ; const timesAlg = ( a ) => ( n ) : Nat => match ( n . _tag ) ( { Zero : constant ( zero ) , Succ : ( ) => plus ( a ) ( n . value ) , } ) ; const times = ( a ) => ( b ) : Nat => cata ( functorNat ) ( timesAlg ( a ) ) ( b ) ; console . log ( toNumber ( plus ( succ ( succ ( zero ) ) ) ( succ ( succ ( succ ( zero ) ) ) ) ) ) ; console . log ( toNumber ( times ( succ ( succ ( zero ) ) ) ( succ ( succ ( succ ( zero ) ) ) ) ) ) ;