Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fantasy Land compatibility #160

Open
rpominov opened this issue Oct 11, 2015 · 2 comments
Open

Fantasy Land compatibility #160

rpominov opened this issue Oct 11, 2015 · 2 comments

Comments

@rpominov
Copy link
Member

Creating this issue to investigate how we could make Kefir compatible with the Fantasy Land Specification.

I think of two possibilities: add Fantasy Land methods directly into Kefir, or create a plugin as a separate npm package that injects Fantasy Land methods into Kefir. Don't know what is better for us yet, and would like to know your opinions.

In either way first we need to find out how Fantasy Land methods map to current Kefir methods. Here is a draft of such mapping (not sure if it's correct and complete; will update it in progress):

Setoid

a.equals(a) – we can't implement this (?)

Semigroup

a.concat(b)obsA.concat(obsB) (?)

Monoid

m.empty()Kefir.never() (?)

Functor

u.map(f)obs.map(f)

Apply

a.ap(b) — can be implemented on top of combine, although would be better for us (for performance) if FL would require liftN instead of ap

Applicative

a.of(x)Kefir.constant(x) (?)

Foldable

u.reduce(f, x)Kefir.scan(f, x).last() (?)

One problem is that we can't return the result value directly but can only return an observable containing result value. Although FL seem to not require that.

Traversable

u.sequence(of) — not sure...

Here we have the same problem as in reduce — unable to return result value directly:

// we can't do this
Observavble (f a) -> f (Observable a)

// only can do this (based on reduce)
Observavble (f a) -> Observable (f (Observable a))

Observable (f (Observable a)) already doesn't seem to be very useful, but the main problem is that we can't satisfy the following law:

t(u.sequence(f.of)) is equivalent to u.map(t).sequence(g.of) where t is a natural transformation from f to g (naturality)

Although the other way around form of sequencef (Observable a) -> Observavble (f a) seems very similar to Kefir.combine :: [Observable] -> Observable []. Not sure what it gives us though :)

For better understanding here is how sequence for Array looks like:

Array.prototype.sequence = function(of) {
  return this.reduce((r, i) => r.map(xs => x => xs.concat(x)).ap(of(i)), of([]))
}

Chain / Monad

m.chain(f)obs.flatMap(f) (?)

Extend

w.extend(f) — ?

Comonad

w.extract() — can't be implemented because of asynchronous nature of observables (?)

@rpominov
Copy link
Member Author

We still don't have Fantasy Land compatibility, but I've just added Static Land support http://rpominov.github.io/kefir/#static-land

@rpominov
Copy link
Member Author

Here is how Kefir methods map to FL/SL methods btw: https://github.com/rpominov/kefir/blob/29f0cdc472c3f9110fb6563bd5567ecf5d043243/src/interop/static-land.js (missing methods are impossible to implement for Observable)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant