These are chat archives for ramda/ramda

23rd
Sep 2016
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 18:47
This message was deleted
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 18:53
its possible to do some real crazy patterns (see m5 and m6)
LeonineKing1199
@LeonineKing1199
Sep 23 2016 18:56
That's really cool!
I actually really like that interface for handling the insanity that is JS's arrays so a big :plus1: from me
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 18:57
thanks :-) the most annoying part is
that in order to match the ‘type’ of a string. you must do typeof
which retursn a string -.-
LeonineKing1199
@LeonineKing1199
Sep 23 2016 18:59
I'm curious though, would it be possible to replace the strings with constructors?
So instead of 'string', you'd have String
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 18:59
I tried
LeonineKing1199
@LeonineKing1199
Sep 23 2016 18:59
Then it could work for user-defined constructibles as well.
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 18:59
the repl makes it null -.-
For user defined types it works
See m6
 class ABox {
      constructor(v) {
        this.v = v;
      }
    }

    const m6 = matchC([new ABox(5), [new ABox(10), new ABox(20)]])
        .when([ABox, 5], ([a, b]) => [false, a, b])
        .when([ABox, [ABox, ABox]], ([a, b]) => [true, a, b])
        .otherwise(_ => 'no match’);
LeonineKing1199
@LeonineKing1199
Sep 23 2016 19:00
Ooh, that's good.
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 19:00
even works with inheritance
LeonineKing1199
@LeonineKing1199
Sep 23 2016 19:00
But it seems weird that some types would be strings while others would be valid constructibles...
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 19:00
i know
LeonineKing1199
@LeonineKing1199
Sep 23 2016 19:00
The matching on values is nice though.
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 19:01
and functions :-) .when(['_', [100, 100], p => p === 100], ([a, b, c]) => [true, a, b, c])
LeonineKing1199
@LeonineKing1199
Sep 23 2016 19:01
I think that has a lot of power
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 19:01
yes. I hope so. Need to iron out potential bugs I guess but it could be useful
Would that be something for ramda maybe?
Denis Stoyanov
@xgrommx
Sep 23 2016 19:09
@MarkusPfundstein why not just use cond?
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 19:10
didn’t know it existed :-)
yeah matches is ugly
i dont like ti
Denis Stoyanov
@xgrommx
Sep 23 2016 19:11
@MarkusPfundstein reason?
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 19:11
the style how you define your patterns
large strings
Alexandre Theodoro da Silva
@alexandrethsilva
Sep 23 2016 19:12
@xgrommx as a sidenote, matches.js is deprecated. maybe you referred to sparkler?
Denis Stoyanov
@xgrommx
Sep 23 2016 19:13
@alexandrethsilva also outdated https://github.com/natefaubion/sparkler
Alexandre Theodoro da Silva
@alexandrethsilva
Sep 23 2016 19:13
ah yeah, true :D
Alexandre Theodoro da Silva
@alexandrethsilva
Sep 23 2016 19:20
just saw that this natefaubion guy has some really nice stuff
but anyways, off topic
Alastair Hole
@afhole
Sep 23 2016 19:24
Brad Compton (he/him)
@Bradcomp
Sep 23 2016 19:26
@afhole You can use useWith to mimic it.
const on = (final, transform) => useWith(final, [transform, transform])
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 19:27
lol
Alexandre Theodoro da Silva
@alexandrethsilva
Sep 23 2016 19:28
@MarkusPfundstein :+1:
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 19:29
now i just have to get it in shape so that it can be used by the browser as well I guess
I only do node
no idea how browser stuff works
LeonineKing1199
@LeonineKing1199
Sep 23 2016 19:32

no idea how browser stuff works

You can just browserify it. I think your module is awesome, for what it's worth. Keep on keepin' on!

Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 19:33
thanks :-)
I check browserify
LeonineKing1199
@LeonineKing1199
Sep 23 2016 19:51
It wouldn't be possible to get it to work like Haskell's pattern matching, would it?

Something about:

map :: (a->b) -> [a] -> [b]
map f  [] =  []
map f (x:xs) =  f x : map f xs

is just such a neat syntax for pattern matching

Granted, you shouldn't actually map in any language without TCO using recursion but still
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 19:58
actually
I did s.th. like this
mom
need to start laptop
LeonineKing1199
@LeonineKing1199
Sep 23 2016 19:58
Mostly, just letting the user write their strings with the infix operator
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:00

I translated the patterns here: http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf

this is what you can do then for instance:

const [Term, Con, Div] = defData({
    Term: {
        Con: ['a'],
        Div: ['t', 'u']
    }
});

/*
 * first example - Maybe Monad
 */
const eval1 = (term) =>
    match(term)
        .when(Con, t => Maybe.of(t.a))
        .when(Div, d => eval1(d.t).flatMap(a => eval1(d.u).flatMap(b => Maybe.of(a/b))))
        .get();
Denis Stoyanov
@xgrommx
Sep 23 2016 20:00
@MarkusPfundstein probably this isn't necessary https://github.com/MarkusPfundstein/pmatch-js/blob/master/match.js#L20
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:00
(old version of match which didn’t allow deep nesting)
@xgrommx You got me :P
Drew
@dtipson
Sep 23 2016 20:01
@afhole isn't that basically what () is, in a way? It's just not available as an infix operator
Denis Stoyanov
@xgrommx
Sep 23 2016 20:01
@LeonineKing1199 this isn't complicate https://jsbin.com/bumuqa/2/edit?html,js,output (refarding map)
Drew
@dtipson
Sep 23 2016 20:02
i.e. you can't do fn value nor can you do fn () value you have to do fn(value)
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:02
I actually have no idea how the spread operator works lol XD
I'm still using peasant JS
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:03
> [a,b,...c] = [1,2,3,4,5]
[ 1, 2, 3, 4, 5 ]
> a
1
> b
2
> c
[ 3, 4, 5 ]
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:03
Hey, that's pretty nice
That's a Node 6 feature, right?
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:04
yopp
Denis Stoyanov
@xgrommx
Sep 23 2016 20:04
@MarkusPfundstein let {a:b =10, c} = {d:1, f:20, c:10}
Drew
@dtipson
Sep 23 2016 20:04
or with ramda, doing ap([x=>x+1])([5]) in containers is ultimately something similar
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:04
Yeah, still on Node 4
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:04
:O
Denis Stoyanov
@xgrommx
Sep 23 2016 20:04
@MarkusPfundstein rename and default value)
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:04
i migrated our whole prod. environment the day node6 became LTS :P
yeah, destructuring is awesome. Its really a game changer. Destructuring and arrows also make promise based programming much more cool.
Brad Compton (he/him)
@Bradcomp
Sep 23 2016 20:05

the day node6 became LTS

4 is still LTS ;)

Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:05
myP.then(([val,1,val2]) => {x: val1*val2}).then(({x}) => x)
Denis Stoyanov
@xgrommx
Sep 23 2016 20:05
Also this is my favorite now (if you use desktop) https://github.com/princejwesley/Mancy/
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:05
Won't this overflow your stack though:
const map = (f, xs) => {
  let [head, ...tail] = xs;

  switch(xs.length) {
    case 0:
      return [];
    default:
      return [f(head), ...map(f, tail)];
  }
}
Does Node have TCO?
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:05
no
afaik nope
Drew
@dtipson
Sep 23 2016 20:06
not yet
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:06
I'm always skeptical of people using JS for big data so I guess a recursive map actually is alright XD
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:06
MANCY :O :O :O
THIS … IS …. WHAT … I …. NEED
fuck ./node :P
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:06
If anything, it only further punishes people for using JS for big data
Denis Stoyanov
@xgrommx
Sep 23 2016 20:06
I think we don't need implement FP in js! Just use haskell or purescript :smile:
Brad Compton (he/him)
@Bradcomp
Sep 23 2016 20:07
@xgrommx That's cool!
Denis Stoyanov
@xgrommx
Sep 23 2016 20:07
@MarkusPfundstein really powerful tool
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:07
@xgrommx tell that my tech lead -.-
Drew
@dtipson
Sep 23 2016 20:07
the recursive map isn't tco-iazble though, right? because the function isn't the last thing returned
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:07
Yeah, I know it's possible in circumstances where you do that.
But maybe not in that case..
Eh
Denis Stoyanov
@xgrommx
Sep 23 2016 20:07
@dtipson so, you can use Y combinator with memoizing
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:07
You guys, just use a loop XD
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:08
loops are much more difficult
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:08
TCO does that for you anyway
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:08
recursion is like the easiest thing for most algorithmn
Denis Stoyanov
@xgrommx
Sep 23 2016 20:08
const Y = (f, c = new Map, r = void 0) => a => c.has(a) ? c.get(a) : (r = (f( (n ) => (Y(f,c))( n )))( a ), c.set(a, r), r);
const reduce = f => Y(g => y => xs => xs.length < 1 ? y : g(f(y)(head(xs)))(tail(xs)));
map we can implement with reduce =)
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:08
Recursion is iteration, man.
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:08
implement breadt-first search with a loop
and wiht recursion
recursion is much more straightforward
Denis Stoyanov
@xgrommx
Sep 23 2016 20:09
const fib = Y(f => n => n <= 1 ? n : f(n - 1) + f(n - 2));
const fact = Y(f => n => n < 2 ? 1 : f(n-1) * n)
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:09
Yeah... I remember the first time I learned about recursion depth from that too...
Drew
@dtipson
Sep 23 2016 20:09
as I understand it, the point of Y is to implement recursion in combinator systems that don't allow assignment. But in js, we can just assign a function a name and then reference it directly
So Y becomes complete overkill
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:10
I think there's formulaic ways you can convert recursion to iteration though.
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:10
Y looks awesome but I don’t understand it :P
Denis Stoyanov
@xgrommx
Sep 23 2016 20:10
@dtipson no, Y combinator incapsulate recursion
Drew
@dtipson
Sep 23 2016 20:10
unless you are saying that makes a recursion that's hard to express in a TCOish way into something that is TCO-izeable
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:11
I like this implementation of reduce as well:
const fold = (f, seed, xs) => {
  let [head, ...tail] = xs;

  switch(xs.length) {
    case 0:
      return seed;
    default:
      return fold(f, f(seed, head), tail);
  }
}
Drew
@dtipson
Sep 23 2016 20:11
but in the function above, f(n-1) * n is not TCO, because the function is not the last thing run
that reduce version looks TCO to me, otoh
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:11
good catch @dtipson
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:12
Eh. The problem with that is that I think it only evaluates the function as the recursion stack unwinds.
Drew
@dtipson
Sep 23 2016 20:12
const curry = (f, ...args) => (f.length <= args.length) ? f(...args) : (...more) => curry(f, ...args, ...more);
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:12
I bet a loop would be significantly more performant
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:12
to make map above TCO I think you would have to prepend and then reverse at the end
Drew
@dtipson
Sep 23 2016 20:12
(more of an autocurry)
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:13
@LeonineKing1199 yes. in JS most definitely
const head = ([x, ...t]) => x;
const tail = ([x, ...t]) => t;
/*
 * composes a chain of function into a single function
 */
const compose = (f, ...rest) => (x) =>
    rest.length === 1 
    ? head(rest)(f(x))
    : compose(head(rest), ...tail(rest))(f(x));
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:13
I might get flack for this but it's kind of awesome, the Haskell runtime is implemented in C, I think XD
Drew
@dtipson
Sep 23 2016 20:14
in my experience trying to play with it, the problem with implementing operations over lists using rest parameters is that you either have to reverse the list at some point, or give up TCO
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:14
yopp
Brad Compton (he/him)
@Bradcomp
Sep 23 2016 20:15
GHC's runtime system is a slightly scary beast: 50,000 lines of C and C-- code, much of which seems at first glance to be completely obscure.
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:15
at University Bachelor, we had to use Prolog for all Logic related programming… You always needed to get TCO right, which mostly involved reverse at the end :P
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:15
Omg, I forgot C-- was a thing
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:15
wtf is C— ?
Denis Stoyanov
@xgrommx
Sep 23 2016 20:15
function fibonacci(n) {
  var num;

  if (n >= 2) {
    num = fibonacci(n - 1) + fibonacci(n - 2);
  } else {
    num = n
  }

  return num;
}

function fibonacci2(n) {
  function go(n, a, b) {
    switch(n) {
      case 0:
        return a;
      default:
        return go(n - 1, b, a + b);
    }
  }

  return go(n, 0, 1);
}

function fibonacci3(n) {
  var sq5 = Math.sqrt(5);

  var a = (1 + sq5) / 2;
  var b = (1 - sq5) / 2;

  return Math.ceil((Math.pow(a, n) - Math.pow(b, n)) / sq5);
}
last version :smile:
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:15
haha fibonacci3
I remember that from an assignment :D :D :D
first year, first semester, first course (!!!)
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:16

wtf is C— ?

About two steps below C++ :P

Drew
@dtipson
Sep 23 2016 20:16
fibonacci2 is a trampoline, right?
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:16
no, regular recursion
trampoline is if you jump between 2 functions
C-- is low level in Haskell after Core
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:17
Speaking of trampolines, there's this awesome talk about Scala vs the paradigm of FP
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:17
link?
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:17
I don't wanna post it because the title is flame bait
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:17
send me PM
:D
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:18
But it's this guy basically talking about all the abstraction leaks in Scala as it deals with the JVM
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:18
aja, lack of TCO :P
clojure has recur for that
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:18
And trampolines are one of them because I guess people were creating such large monadic compositions that they overflew their stacks
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:18
no idea how its implemented,
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:19
I sent you the link
So yeah, be careful about the languages you choose. FP is kind of built on TCO
Denis Stoyanov
@xgrommx
Sep 23 2016 20:21
My point! use haskell and purescript :smile:
but we need adt in js :smile:
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:22
Saying JS needs types is a massive understatement lol XD
Denis Stoyanov
@xgrommx
Sep 23 2016 20:23
wtf?!
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:24
I can't even consider a language worth using if its verbosity doesn't at least match:
template <
  typename T,
  typename = std::enable_if<std::is_floating_point<T>::value>::type
>
The more words the better XD
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:25
class Tree {
        constructor(left, right) {
                this.left = left;
                this.right = right;
        }
}

class Node {
        constructor(value) {
                this.value = value;
        }
}

const T = (l, r) => new Tree(l, r);
const N = v => new Node(v);

const dfs = (t) => match(t)
        .when(Node, v => console.log(v.value))
        .when(Tree, t => { dfs(t.left); dfs(t.right)})
        .otherwise(_ => 'error');

dfs(T(T(N(5), T(N(7), N(1))), T(N(-1), N(8))));
// 5
7
1
-1
8
without recursion this would be a pain though. I hope we can get TCO into node7++
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:27
Forget TCO, I just want this to throw: [] + {}
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:27
:thumbsup:
‘5’ + 3
:P
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:27
One fire at a time, man.
TCO would be nice but it's not more important than silently doing whatever with such gross type mismatches
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:28
@xgrommx yeah, I need to check union-types. wasn’t aware of them since… yesterday?
I wonder how much websites would break if they would throw [] + {}
you have no idea what kind of js you encouter in the wild
LeonineKing1199
@LeonineKing1199
Sep 23 2016 20:28
Who's coding like that in first place and then actually relying on it? O_o
Denis Stoyanov
@xgrommx
Sep 23 2016 20:29
@MarkusPfundstein also https://github.com/puffnfresh/daggy but union-type is my choose
Brad Compton (he/him)
@Bradcomp
Sep 23 2016 20:31
It looks like the new Folktale will have an ADT module as well.
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:32
@xgrommx thx
Denis Stoyanov
@xgrommx
Sep 23 2016 20:33
@Bradcomp ?
Drew
@dtipson
Sep 23 2016 20:35
similar to daggy's?
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:37
const fibbonacci = (n) => {
        const go = (n, a, b) => {
                return match(n)
                        .when(0, _ => a)
                        .otherwise(_ => go(n - 1, b, a +b));
        }
        return go(n, 0, 1);
}

console.log(fibbonacci(25));

const factorial = (n) => match(n)
        .when(0, _ => 1)
        .otherwise(n => n * factorial(n - 1));

console.log(factorial(10))
kinda works :-)
maybe I make the second parameter to when not necessarily a function
Drew
@dtipson
Sep 23 2016 20:56
probably contains multiple errors and misstatements in the docs, but I had fun exploring how to create types with a similar pattern to daggy's here: https://github.com/dtipson/NELs
implements linked lists, circular linked lists, circular doubly linked lists (which has been done a million times before, but was a fun learning exercise). Most interesting/useful for the comonad and generator interfaces
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 20:58
@xgrommx
const mappy = (f, xs) => match(xs)
        .when([], v => [])
        .otherwise(([x, ...xs]) => [f(x), ...mappy(f, xs)]);
@dtipson nice. what is the actual literature abotu this?
Drew
@dtipson
Sep 23 2016 21:01
about linked lists? Just your basic cons lists, but circular. So in the extreme case, a list of one thing has a .before/.tail that link to itself, and so on, forming a ring. The FL interfaces like map walk the list finitely, generators can iterate infinitely. It's a much more useful/intelligible structure for cellular automata using .extend, for instance. https://goo.gl/DdKYZL
Denis Stoyanov
@xgrommx
Sep 23 2016 21:03
Drew
@dtipson
Sep 23 2016 21:04
(that uses an extend method that just pretends native Arrays are circular, an actual circular list is even more straightforward)
Markus Pfundstein
@MarkusPfundstein
Sep 23 2016 21:05
no about union types etc
Drew
@dtipson
Sep 23 2016 21:05
that's if b is not curried
I have it in two flavors in another repoconst S = f => g => x => f(x)(g(x)); const S2 = f => g => x => f(x, g(x));
I actually have only found one usage for that combinator recently: in implementing Function.prototype.ap
it's pretty neat tho
Denis Stoyanov
@xgrommx
Sep 23 2016 21:08
let x = \f -> f(\x y -> x)(\x y z -> x z $ y z)(\x y -> x)

let s = x (x x)
let k = x x x
let b = s (k s) k

let lift = b(b(s))(b)

let i = s k k
let w = s s (s k)
let w'' = b (b w)
let c = s (b b s) (k k)
let q = c b
let join = w;
let bind' = w'' b
let bind = w'' q
let fish = b (b (b w)) (c (b b b))
let fish' = c fish

-- comonad
let extract = k i
let duplicate = w b
let extend = b (b duplicate) b
Drew
@dtipson
Sep 23 2016 21:10
ooo, definitely have to work through that definition of extend
looks very instructive
Denis Stoyanov
@xgrommx
Sep 23 2016 21:17
@dtipson this is functor, monad, applicative for Function with only pointfree style (combinators calculus)
and comonad :smile:
Drew
@dtipson
Sep 23 2016 21:19
yeah, it's super neat
Denis Stoyanov
@xgrommx
Sep 23 2016 21:20
it was just for fun :smile:
also only pointfree
import Prelude (Show, print, (++), (*), ($)) 

infixl 4 <*>, <**>, <*, *>, <$>, <$$>, <$
infixl 1 >>=, >>
infixr 1 =<<

s x y z = (x z)(y z)
k x y = x
i = s k k
b = s (k s) k
c = s (b b s) (k k)
w = s s (s k)
w'' = b (b w)
q = c b
liftA2 = b (b (<*>)) (<$>) 

data Maybe a = Just a | Nothing deriving (Show)

foldr f z [] = z 
foldr f z (x:xs) = f x (foldr f z xs)

concatMap = b (c foldr ([])) (b (c (++)))

maybe n f a = case a of
  Just v -> f v
  Nothing -> n

class Functor f where
  fmap, (<$>) :: (a -> b) -> f a -> f b
  (<$>) = fmap

  (<$$>) :: f a -> (a -> b) -> f b
  (<$$>) = c $ (<$>)

  (<$) :: a -> f b -> f a
  (<$) = b (<$>) k

class (Functor f) => Applicative f where
  pure :: a -> f a
  (<*>) :: f (a -> b) -> f a -> f b

  (*>) :: f a -> f b -> f b
  (*>) = b (<*>) (i <$)

  (<*) :: f a -> f b -> f a
  (<*) = liftA2 k

  (<**>) :: f a -> f (a -> b) -> f b
  (<**>) = liftA2 (c ($))

class (Applicative f) => Monad f where
  (>>=) :: f a -> (a -> f b) -> f b
  (=<<) :: (a -> f b) -> f a -> f b
  (=<<) = c $ (>>=)
  (>>) :: f a -> f b -> f b
  (>>) = b (c b k) (>>=)
  join :: f (f a) -> f a
  join = (>>= i)

instance Functor Maybe where
  fmap = b (maybe Nothing) (b Just)

instance Functor ((->) r) where
  fmap = b

instance Functor [] where
  fmap = b concatMap (b (:[]))

instance Applicative Maybe where
  pure = Just
  (<*>) = c $ b (maybe Nothing) (<$$>)

instance Applicative [] where
  pure = (:[])
  (<*>) = b (c b (c fmap)) (c concatMap)

instance Applicative ((->) r) where
  pure = k
  (<*>) = s

instance Monad Maybe where
  (>>=) = c $ maybe Nothing

instance Monad ((->) r) where
  (>>=) = w'' q

instance Monad [] where
  (>>=) = c concatMap
Denis Stoyanov
@xgrommx
Sep 23 2016 21:31
in js generators could be use as Traverse [Tree a] -> Tree [a] https://jsbin.com/dehetas/3/edit?html,js,console