import { Monoid } from "./monoid" ; import { Applicative , ApplicativeDictionary , lift } from "./applicative" ; import { Traversable , traversable } from "./traversable" ; import { Monad , monad } from "./monad" ; import { Either } from "./either" ; @ monad @ traversable export class Cons < A > implements Monoid < Cons < A > > , Monad < A > , Traversable < A > { constructor ( private val , private tail ) { } combine ( c ) { return this === nil ? c : cons ( this . val , this . tail . combine ( c ) ) ; } identity ( ) { return nil ; } of < B > ( b ) { return cons ( b , nil ) ; } chain < B > ( f ) { return this === nil ? nil : f ( this . val ) . combine ( this . tail . chain ( f ) ) ; } traverse < B > ( a , f ) { return this === nil ? a . of ( nil ) : lift ( cons , f ( this . val ) , this . tail . traverse ( a , f ) ) ; } map : < B > ( f : ( a : A ) => B ) => Cons < B > ; mapTo : < B > ( b : B ) => Cons < B > ; ap : < B > ( a : Monad < ( a : A ) => B > ) => Cons < B > ; lift : ( f : Function , ... ms : any [ ] ) => Cons < any > ; multi : boolean ; flatten : ( ) => Cons < any > ; foldr : < B > ( f : ( a : A , b : B ) => B , acc : B ) => B ; foldl : < B > ( f : ( acc : B , a : A ) => B , init : B ) => B ; sequence : < A > ( a : ApplicativeDictionary , t : Cons < Applicative < A > > ) => Applicative < Traversable < A > > ; shortFoldr : < B > ( f : ( a : A , b : B ) => Either < B , B > , acc : B ) => B ; shortFoldl : < B > ( f : ( acc : B , a : A ) => Either < B , B > , acc : B ) => B ; size : ( ) => number ; maximum : ( ) => number ; minimum : ( ) => number ; sum : ( ) => number ; } export const nil = new Cons ( undefined , undefined ) ; export function cons < A > ( a , as ) { return new Cons ( a , as ) ; } export function fromArray < A > ( as ) { return as . length === 0 ? nil : cons ( as [ 0 ] , fromArray ( as . slice ( 1 ) ) ) ; }