(aka "Algebraic JavaScript Specification")
Este projeto especifica interoperabilidade das estruturas algébricas comum:
Uma álgebra é um conjunto de valores, um conjunto de operadores que está fechado e sob algumas leis que devem obedecer.
Cada álgebra Fantasy Land é uma especificação separada. Uma álgebra pode ter dependências de outras álgebras que devem ser executadas. Uma álgebra também pode indicar outros métodos de álgebra que não precisam de ser implementados e como eles podem ser derivados a partir de novos métodos.
- "value" é qualquer valor JavaScript, incluindo a que tem as estruturas definidas abaixo.
- "equivalent" é uma definição adequada de equivalência para o valor dado.
A definição deve garantir que os dois valores podem ser trocados de forma segura em um programa que respeite abstrações. Por exemplo:
- Duas listas são equivalentes se elas são equivalentes em todos os índices.
- Dois objetos JavaScript antigos simples, interpretadas como dicionários, são equivalentes quando eles são equivalentes para todas as chaves.
- Duas promessas são equivalentes quando deu valores equivalentes.
- Duas funções são equivalentes se conduzirem a resultados equivalentes para as entradas equivalentes.
a.equals(a) === true(reflexividade)a.equals(b) === b.equals(a)(simetria)- If
a.equals(b)andb.equals(c), thena.equals(c)(transitividade)
Um valor que tem uma Setoid deve fornecer um método equals. O
método equals recebe um argumento:
a.equals(b)
-
bdeve ser um valor da mesma Setoid- Se
Bnão é o mesmo Setoid, comportamento deequalsé não especificado (recomendado voltarfalse).
- Se
-
equalsdeve retornar um boolean (outruefalse).
a.concat(b).concat(c)é equivalente aa.concat(b.concat(c))(associatividade)
Um valor que tem uma Semigroup deve fornecer um método concat. O
método concat recebe um argumento:
s.concat(b)
-
bdeve ser um valor da mesma Semigroup- Se
Bnão é o mesmo semigroup, comportamento de 'é concat` não especificado.
- Se
-
concatdeve retornar um valor do mesmo Semigroup.
Um valor que implementa a especificação Monoid também deve implementar a especificação Semigroup.
m.concat(m.empty())is equivalent tom(right identity)m.empty().concat(m)is equivalent tom(left identity)
Um valor que tem uma Monoid deve fornecer um método empty sobre si mesma ou seu objeto constructor. O método empty não tem argumentos:
m.empty()
m.constructor.empty()
emptydeve retornar um valor do mesmo Monoid
u.map(function(a) { return a; })é equivalente au(identidade)u.map(function(x) { return f(g(x)); })é equivalente au.map(g).map(f)(composição)
Um valor que tem uma Functor deve fornecer um método map. O map
método tem um argumento:
u.map(f)
-
fdeve ser uma função,1.Se
fnão é uma função, o comportamento domapé não especificado. 2.fpode retornar qualquer valor. -
mapdeve retornar um valor do mesmo Functor
Um valor que implementa a especificação Apply deve também implementar a especificação Functor.
a.map(function(f) { return function(g) { return function(x) { return f(g(x))}; }; }).ap(u).ap(v)is equivalent toa.ap(u.ap(v))(composition)
Um valor que tem uma Apply deve fornecer um método ap. O ap
método recebe um argumento:
a.ap(b)
-
adeve ser uma função de um Aplicar,- Se
anão representa uma função, o comportamento doapnão é especificado.
- Se
-
bdeve ser um Apply de qualquer valor -
apdeve aplicar-se a função em Applyaao valor em AplicarB
Um valor que implementa a especificação Applicative deve também implementar a especificação Apply.
A value which satisfies the specification of an Applicative does not need to implement:
- Functor's
map; derivable asfunction(f) { return this.of(f).ap(this); }
a.of(function(x) { return x; }).ap(v)is equivalent tov(identity)a.of(f).ap(a.of(x))is equivalent toa.of(f(x))(homomorphism)u.ap(a.of(y))is equivalent toa.of(function(f) { return f(y); }).ap(u)(interchange)
A value which has an Applicative must provide an of method on itself
or its constructor object. The of method takes one argument:
a.of(b)
a.constructor.of(b)
-
ofmust provide a value of the same Applicative- No parts of
bshould be checked
- No parts of
u.reduceis equivalent tou.toArray().reduce
toArray; derivable asfunction() { return this.reduce(function(acc, x) { return acc.concat(x); }, []); }
A value which has a Foldable must provide a reduce method. The reduce
method takes two arguments:
u.reduce(f, x)
-
fmust be a binary function- if
fis not a function, the behaviour ofreduceis unspecified. - The first argument to
fmust be the same type asx. fmust return a value of the same type asx
- if
-
xis the initial accumulator value for the reduction
A value that implements the Traversable specification must also implement the Functor specification.
-
t(u.sequence(f.of))is equivalent tou.map(t).sequence(g.of)wheretis a natural transformation fromftog(naturality) -
u.map(function(x){ return Id(x); }).sequence(Id.of)is equivalent toId.of(identity) -
u.map(Compose).sequence(Compose.of)is equivalent toCompose(u.sequence(f.of).map(function(x) { return x.sequence(g.of); }))(composition)
traverse; derivable asfunction(f, of) { return this.map(f).sequence(of); }
A value which has a Traversable must provide a sequence method. The sequence
method takes one argument:
u.sequence(of)
ofmust return the Applicative thatucontains.
A value that implements the Chain specification must also implement the Apply specification.
A value which satisfies the specification of a Chain does not need to implement:
- Apply's
ap; derivable asfunction ap(m) { return this.chain(function(f) { return m.map(f); }); }
m.chain(f).chain(g)is equivalent tom.chain(function(x) { return f(x).chain(g); })(associativity)
A value which has a Chain must provide a chain method. The chain
method takes one argument:
m.chain(f)
-
fmust be a function which returns a value- If
fis not a function, the behaviour ofchainis unspecified. fmust return a value of the same Chain
- If
-
chainmust return a value of the same Chain
A value that implements the Monad specification must also implement the Applicative and Chain specifications.
A value which satisfies the specification of a Monad does not need to implement:
- Apply's
ap; derivable asfunction(m) { return this.chain(function(f) { return m.map(f); }); } - Functor's
map; derivable asfunction(f) { var m = this; return m.chain(function(a) { return m.of(f(a)); })}
m.of(a).chain(f)is equivalent tof(a)(left identity)m.chain(m.of)is equivalent tom(right identity)
w.extend(g).extend(f)is equivalent tow.extend( function(_w){ return f( _w.extend(g) ); } )
An Extend must provide an extend method. The extend
method takes one argument:
w.extend(f)
-
fmust be a function which returns a value- If
fis not a function, the behaviour ofextendis unspecified. fmust return a value of typev, for some variablevcontained inw.
- If
-
extendmust return a value of the same Extend.
A value that implements the Comonad specification must also implement the Functor and Extend specifications.
w.extend(function(_w){ return _w.extract(); })is equivalent toww.extend(f).extract()is equivalent tof(w)w.extend(f)is equivalent tow.extend(function(x) { return x; }).map(f)
A value which has a Comonad must provide an extract method on itself.
The extract method takes no arguments:
c.extract()
extractmust return a value of typev, for some variablevcontained inw.vmust have the same type thatfreturns inextend.
- If there's more than a single way to implement the methods and laws, the implementation should choose one and provide wrappers for other uses.
- It's discouraged to overload the specified methods. It can easily result in broken and buggy behaviour.
- It is recommended to throw an exception on unspecified behaviour.
- An
Idcontainer which implements all methods is provided inid.js.

