1.0.3 • Published 10 months ago

@nathrach/early-birds v1.0.3

Weekly downloads
-
License
MIT
Repository
gitlab
Last release
10 months ago

early-birds

early-birds, like fantasy-birds, is a port of the haskell package Data.Aviary.Birds.

Install

npm i @nathrach/early-birds

Differences between early-birds and fantasy-birds

For many combinators, the behaviour of early-birds will (modulo bugs) be identical to that of fantasy-birds. early-birds differs in that intermediate results are eagerly evaluated, e.g. for the idstarstar bird, (a -> b -> c) -> a -> b -> c, idstarstar(f)(x) will evalute f(x) as soon as x is provided. The intermediate results are also "closed over" so that the evaluation occurs only once.

Consider the following example module which demonstrates the differences.

import { psi } from "../src/early-birds.mjs"
const F = require ("fantasy-birds")

const psiEarly = psi

const psiFantasy = F.psi

const toLower = string => (
  console.log (`!---- evaluating "${string}".toLowerCase() ----!`),
  string.toLowerCase()
)

const equal3 = x => y => x === y

const tests = [ 'true', 'True', 'TruE', 'false', 'False', 'FalsE' ]

// --- Using early-birds
console.log ('\n !#### Testing with psiEarly ####!\n')

const isTrueEarly = psiEarly (equal3) (toLower) ('TRUE')

tests.map (e => console.log (`Testing isTrueEarly ("${e}"): ${isTrueEarly (e)}\n`))

// --- Using fantasy-birds
console.log ('\n!#### Testing with psiFantasy ####!\n')

const isTrueFantasy = psiFantasy (equal3) (toLower) ('TRUE')

tests.map (e => console.log (`Testing isTrue ("${e}"): ${isTrueFantasy (e)}\n`))

When this module is imported into node.js the following is output:

> await import ('./examples/sameLetters.mjs')

 !#### Testing with psiEarly ####!

!---- evaluating "TRUE".toLowerCase() ----!
!---- evaluating "true".toLowerCase() ----!
Testing isTrueEarly ("true"): true

!---- evaluating "True".toLowerCase() ----!
Testing isTrueEarly ("True"): true

!---- evaluating "TruE".toLowerCase() ----!
Testing isTrueEarly ("TruE"): true

!---- evaluating "false".toLowerCase() ----!
Testing isTrueEarly ("false"): false

!---- evaluating "False".toLowerCase() ----!
Testing isTrueEarly ("False"): false

!---- evaluating "FalsE".toLowerCase() ----!
Testing isTrueEarly ("FalsE"): false

!#### Testing with psiFantasy ####!

!---- evaluating "TRUE".toLowerCase() ----!
!---- evaluating "true".toLowerCase() ----!
Testing isTrue ("true"): true

!---- evaluating "TRUE".toLowerCase() ----!
!---- evaluating "True".toLowerCase() ----!
Testing isTrue ("True"): true

!---- evaluating "TRUE".toLowerCase() ----!
!---- evaluating "TruE".toLowerCase() ----!
Testing isTrue ("TruE"): true

!---- evaluating "TRUE".toLowerCase() ----!
!---- evaluating "false".toLowerCase() ----!
Testing isTrue ("false"): false

!---- evaluating "TRUE".toLowerCase() ----!
!---- evaluating "False".toLowerCase() ----!
Testing isTrue ("False"): false

!---- evaluating "TRUE".toLowerCase() ----!
!---- evaluating "FalsE".toLowerCase() ----!
Testing isTrue ("FalsE"): false

[Module: null prototype] {  }
> 

In the example, "TRUE".toLowerCase is evaluted only once for the early-birds psi and is evaluted for each test for the fantasy-birds psi. The eager closure can be useful when applying the combinators to pure functions since the evaluation will always be the same. However, for applications that rely on the side effects, the fantasy-birds behaviour is likely what is desired.

The Aviary

applicator :: (a -⁠> b) -⁠> a -⁠> b

  • I* combinator
  • λ abstraction: λab.ab

becard :: (c -⁠> d) -⁠> (b -⁠> c) -⁠> (a -⁠> b) -⁠> a -⁠> d

  • B3 combinator
  • λ abstraction: λabcd.a(b(cd))

blackbird :: (c -⁠> d) -⁠> (a -⁠> b -⁠> c) -⁠> a -⁠> b -⁠> d

  • B1 combinator
  • λ abstraction: λabcd.a(bcd)

bluebird :: (b -⁠> c) -⁠> (a -⁠> b) -⁠> a -⁠> c

  • B combinator
  • λ abstraction: λabc.a(bc)

bluebird_ :: (a -⁠> c -⁠> d) -⁠> a -⁠> (b -⁠> c) -⁠> b -⁠> d

  • B' combinator
  • λ abstraction: λabcd.ab(cd)

bunting :: (d -⁠> e) -⁠> (a -⁠> b -⁠> c -⁠> d) -⁠> a -⁠> b -⁠> c -⁠> e

  • B2 combinator
  • λ abstraction: λabcde.a(bcde)

cardinal :: (a -⁠> b -⁠> c) -⁠> b -⁠> a -⁠> c

  • C combinator
  • λ abstraction: λabc.acb

cardinal_ :: (c -⁠> a -⁠> d) -⁠> (b -⁠> c) -⁠> a -⁠> b -⁠> d

  • C' combinator
  • λ abstraction: λabcd.a(bd)c

cardinalstar :: (a -⁠> c -⁠> b -⁠> d) -⁠> a -⁠> b -⁠> c -⁠> d

  • C* combinator
  • λ abstraction: λabcd.abdc

cardinalstarstar :: (a -⁠> b -⁠> d -⁠> c -⁠> e) -⁠> a -⁠> b -⁠> c -⁠> d -⁠> e

  • C** combinator
  • λ abstraction: λabcde.abced

dickcissel :: (a -⁠> b -⁠> d -⁠> e) -⁠> a -⁠> b -⁠> (c -⁠> d) -⁠> c -⁠> e

  • D1 combinator
  • λ abstraction: λabcde.abc(de)

dove :: (a -⁠> c -⁠> d) -⁠> a -⁠> (b -⁠> c) -⁠> b -⁠> d

  • D combinator
  • λ abstraction: λabcd.ab(cd)

dovekie :: (c -⁠> d -⁠> e) -⁠> (a -⁠> c) -⁠> a -⁠> (b -⁠> d) -⁠> b -⁠> e

  • D2 combinator
  • λ abstraction: λabcde.a(bc)(de)

eagle :: (a -⁠> d -⁠> e) -⁠> a -⁠> (b -⁠> c -⁠> d) -⁠> b -⁠> c -⁠> e

  • E combinator
  • λ abstraction: λabcde.ab(cde)

eaglebald :: (e -⁠> f -⁠> g) -⁠> (a -⁠> b -⁠> e) -⁠> a -⁠> b -⁠> (c -⁠> d -⁠> f) -⁠> c -⁠> d -⁠> g

  • E^ combinator
  • λ abstraction: λabcdefg.a(bcd)(efg)

finch :: a -⁠> b -⁠> (b -⁠> a -⁠> c) -⁠> c

  • F combinator
  • λ abstraction: λabc.cba

finchstar :: (c -⁠> b -⁠> a -⁠> d) -⁠> a -⁠> b -⁠> c -⁠> d

  • F* combinator
  • λ abstraction: λabcd.adcb

finchstarstar :: (a -⁠> d -⁠> c -⁠> b -⁠> e) -⁠> a -⁠> b -⁠> c -⁠> d -⁠> e

  • F** combinator
  • λ abstraction: λabcde.abedc

goldfinch :: (b -⁠> c -⁠> d) -⁠> (a -⁠> c) -⁠> a -⁠> b -⁠> d

  • G combinator
  • λ abstraction: λabcd.ad(bc)

hummingbird :: (a -⁠> b -⁠> a -⁠> c) -⁠> a -⁠> b -⁠> c

  • H combinator
  • λ abstraction: λabc.abcb

idiot :: a -⁠> a

  • I combinator
  • λ abstraction: λa.a

idstar :: (a -⁠> b) -⁠> a -⁠> b

  • I* combinator
  • λ abstraction: λab.ab

idstarstar :: (a -⁠> b -⁠> c) -⁠> a -⁠> b -⁠> c

  • I** combinator
  • λ abstraction: λabc.abc

jalt :: (a -⁠> c) -⁠> a -⁠> b -⁠> c

  • jalt combinator
  • λ abstraction: λabc.ab

jalt_ :: (a -⁠> b -⁠> d) -⁠> a -⁠> b -⁠> c -⁠> d

  • jalt' combinator
  • λ abstraction: λabcd.abc

jay :: (a -⁠> b -⁠> b) -⁠> a -⁠> b -⁠> a -⁠> b

  • J combinator
  • λ abstraction: λabcd.ab(adc)

kestrel :: a -⁠> b -⁠> a

  • K combinator
  • λ abstraction: λab.a

kite :: a -⁠> b -⁠> b

  • Ki combinator
  • λ abstraction: λab.b

owl :: ((a -⁠> b) -⁠> a) -⁠> (a -⁠> b) -⁠> b

  • O combinator
  • λ abstraction: λab.b(ab)

phoenix :: (b -⁠> c -⁠> d) -⁠> (a -⁠> b) -⁠> (a -⁠> c) -⁠> a -⁠> d

  • S' combinator
  • λ abstraction: λabcd.a(bd)(cd)

  • same as starling_

psi :: (b -⁠> b -⁠> c) -⁠> (a -⁠> b) -⁠> a -⁠> a -⁠> c

  • Psi combinator
  • λ abstraction: λabcd.a(bc)(bd)

quacky :: a -⁠> (a -⁠> b) -⁠> (b -⁠> c) -⁠> c

  • Q4 combinator
  • λ abstraction: λabc.c(ba)

queer :: (a -⁠> b) -⁠> (b -⁠> c) -⁠> a -⁠> c

  • Q combinator
  • λ abstraction: λabc.b(ac)

quirky :: (a -⁠> b) -⁠> a -⁠> (b -⁠> c) -⁠> c

  • Q3 combinator
  • λ abstraction: λabc.c(ab)

quixotic :: (b -⁠> c) -⁠> a -⁠> (a -⁠> b) -⁠> c

  • Q1 combinator
  • λ abstraction: λabc.a(cb)

quizzical :: a -⁠> (b -⁠> c) -⁠> (a -⁠> b) -⁠> c

  • Q2 combinator
  • λ abstraction: λabc.b(ca)

robin :: a -⁠> (b -⁠> a -⁠> c) -⁠> b -⁠> c

  • R combinator
  • λ abstraction: λabc.bca

robinstar :: (b -⁠> c -⁠> a -⁠> d) -⁠> a -⁠> b -⁠> c -⁠> d

  • R* combinator
  • λ abstraction: λabcd.acdb

robinstarstar :: (a -⁠> c -⁠> d -⁠> b -⁠> e) -⁠> a -⁠> b -⁠> c -⁠> d -⁠> e

  • R** combinator
  • λ abstraction: λabcde.abdec

starling :: (a -⁠> b -⁠> c) -⁠> (a -⁠> b) -⁠> a -⁠> c

  • S combinator
  • λ abstraction: λabc.ac(bc)

starling_ :: (b -⁠> c -⁠> d) -⁠> (a -⁠> b) -⁠> (a -⁠> c) -⁠> a -⁠> d

  • S' combinator
  • λ abstraction: λabcd.a(bd)(cd)

  • same as phoenix

thrush :: a -⁠> (a -⁠> b) -⁠> b

  • T combinator
  • λ abstraction: λab.ba

vireo :: a -⁠> b -⁠> (a -⁠> b -⁠> c) -⁠> c

  • V combinator
  • λ abstraction: λabc.cab

vireostar :: (b -⁠> a -⁠> b -⁠> d) -⁠> a -⁠> b -⁠> b -⁠> d

  • V* combinator
  • λ abstraction: λabcd.acbd

vireostarstar :: (a -⁠> c -⁠> b -⁠> c -⁠> e) -⁠> a -⁠> b -⁠> c -⁠> c -⁠> e

  • V** combinator
  • λ abstraction: λabcde.abecd

warbler :: (a -⁠> a -⁠> b) -⁠> a -⁠> b

  • W combinator
  • λ abstraction: λab.abb

warbler1 :: a -⁠> (a -⁠> a -⁠> b) -⁠> b

  • W1 combinator
  • λ abstraction: λab.baa

warblerstar :: (a -⁠> b -⁠> b -⁠> c) -⁠> a -⁠> b -⁠> c

  • W* combinator
  • λ abstraction: λabc.abcc

warblerstarstar :: (a -⁠> b -⁠> c -⁠> c -⁠> d) -⁠> a -⁠> b -⁠> c -⁠> d

  • W** combinator
  • λ abstraction: λabcd.abcdd
1.0.3

10 months ago

1.0.2

10 months ago

1.0.1

10 months ago

1.0.0

10 months ago