import { Monoid , MonoidDictionary , AnyMonoid , identity } from "./monoid" ; import { Monad , AbstractMonad } from "./monad" ; import { combine } from './semigroup' ; export class Writer < W extends AnyMonoid < W > , A > extends AbstractMonad < A > { constructor ( public identity , public state , public value ) { super ( ) ; } of < B > ( value ) { return new Writer ( this . identity , this . identity , value ) ; } chain < B > ( f ) { const { state , value } = f ( this . value ) ; return new Writer ( this . identity , combine ( this . state , state ) , value ) ; } multi : boolean = false ; } export function runWriter < W extends Monoid < W > , A > ( w ) { return [ w . state , w . value ] ; } export type WriterFunctions < W extends AnyMonoid < W > > = { tell < A > ( w ) : Writer < W , { } > ; listen < A > ( w ) : Writer < W , [ A , W ] > ; of < A > ( a ) : Writer < W , A > ; multi : boolean ; } ; export function createWriter ( mc ) ; export function createWriter ( mc ) ; export function createWriter < M extends Monoid < M > > ( mc ) ; export function createWriter < M extends Monoid < M > > ( mc ) { const identityElm = identity ( mc ) ; return { tell ( w ) { return new Writer ( identityElm , w , { } ) ; } , listen < A > ( m ) { const value = [ m . value , m . state ] ; return new Writer ( identityElm , m . state , value ) ; } , of < A > ( a ) { return new Writer ( identityElm , identityElm , a ) ; } , multi : false } ; }