Last active
January 30, 2017 22:38
-
-
Save ktec/51fdcad2d5d002081f551a0c5b4b2b5c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// const Box = x => | |
// ({ | |
// map: f => Box(f(x)), | |
// fold: f => f(x), | |
// inspect: () => `Box(${x})` | |
// }) | |
const fmap = f => xs => xs.map(x => f(x)) | |
const cons = (a, b) => a.concat(b) | |
// const cons = (x, xs) => [x].concat(xs) | |
const car = xs => xs[0] // head | |
const cdr = xs => xs.slice(1) // tail | |
const foldr = (f, v, xs) => xs.reduceRight(f, v) | |
const foldl = (f, v, xs) => xs.reduce(f, v) | |
const id = x => x | |
// const map = (f, xs) => foldr((acc, curr) => cons(f(curr), acc), [], xs) | |
const map = (f, xs) => xs.map(f) | |
const Sum = x => | |
({ | |
x, | |
concat: ({x: y}) => Sum(x + y), | |
inspect: () => `Sum(${x})` | |
}) | |
Sum.empty = () => Sum(0) | |
const getSum = m => m.x | |
// Haskell version: | |
// data Fold i o = forall m . Monoid m => Fold (i -> m) (m -> o) | |
// import Data.Monoid | |
// import Prelude hiding (sum) | |
// | |
// import qualified Data.Foldable | |
// | |
// data Fold i o = forall m . Monoid m => Fold (i -> m) (m -> o) | |
// | |
// fold :: Fold i o :: [i] -> o | |
// fold (Fold tally summarise) is = summarise ( reduce (map tally is) ) | |
// where | |
// reduce = Data.Foldable.foldl' (<>) mempty | |
// | |
// sum :: Num n => Fold n n | |
// sum = Fold Sum getSum | |
// | |
// | |
// >>> fold sum [1..10] | |
// 55 | |
// | |
// -- sum = Fold Sum getSum | |
// = print (fold (Fold Sum getSum) [1, 2, 3, 4]) | |
// | |
// -- fold (Fold tally summarize) is = summarize (reduce (map tally is)) | |
// = print (getSum (reduce (map Sum [1, 2, 3, 4]))) | |
// | |
// -- reduce = foldl' (<>) mempty | |
// = print (getSum (foldl' (<>) mempty (map Sum [1, 2, 3, 4]))) | |
// | |
// -- Definition of `map` (skipping a few steps) | |
// = print (getSum (foldl' (<>) mempty [Sum 1, Sum 2, Sum 3, Sum 4])) | |
// | |
// -- `foldl' (<>) mempty` (skipping a few steps) | |
// = print (getSum (mempty <> Sum 1 <> Sum 2 <> Sum 3 <> Sum 4)) | |
// | |
// -- mempty = Sum 0 | |
// = print (getSum (Sum 0 <> Sum 1 <> Sum 2 <> Sum 3 <> Sum 4)) | |
// | |
// -- Sum x <> Sum y = Sum (x + y) | |
// = print (getSum (Sum 10)) | |
// | |
// -- getSum (Sum x) = x | |
// = print 10 | |
// const result = Sum(1).concat(Sum(2)) | |
const mempty = Sum.empty | |
// = print (getSum (Sum 0 <> Sum 1 <> Sum 2 <> Sum 3 <> Sum 4)) | |
// result = getSum(result) | |
// result = getSum(mempty.concat(Sum(1).concat(Sum(2).concat(Sum(3).concat(Sum(4)))))) | |
// map Sum [1, 2, 3, 4] # => [Sum 1, Sum 2, Sum 3, Sum 4] | |
// result = foldl(cons, Sum.empty, map(Sum, [1, 2, 3, 4])) | |
// result = Sum(0).concat(Sum(1).concat(Sum(2).concat(Sum(3).concat(Sum(4))))) | |
// xs = map(Sum, [1, 2, 3, 4]) // [ Sum(1), Sum(2), Sum(3), Sum(4) ] | |
// this works: | |
// result = cons(mempty(), [ Sum(1), Sum(2), Sum(3), Sum(4) ]) | |
// [ Sum(0), Sum(1), Sum(2), Sum(3), Sum(4) ] | |
result = getSum(foldl(cons, mempty(), map(Sum, [1, 2, 3, 4]))) | |
console.log(result) |
Wait, might be doing something like this:
foldl(cons, mempty(), [ Sum(1), Sum(2), Sum(3), Sum(4) ])
foldl(cons, Sum(0), [ Sum(1), Sum(2), Sum(3), Sum(4) ]) // inline mempty()
[ Sum(1), Sum(2), Sum(3), Sum(4) ]).reduce(cons, Sum(0)) // inline foldl
[ Sum(1), Sum(2), Sum(3), Sum(4) ]).reduce((x, xs) => [x].concat(xs), Sum(0)) // inline cons
// running reduce
[ Sum(2), Sum(3), Sum(4) ]).reduce((x, xs) => [Sum(1)].concat(Sum(0)))
// [Sum(1)]
[ Sum(3), Sum(4) ]).reduce((x, xs) => [Sum(2)].concat([Sum(1)]))
// [Sum(2), Sum(1)]
[ Sum(4) ]).reduce((x, xs) => [Sum(3)].concat([Sum(2), Sum(1)]))
// [Sum(3), Sum(2), Sum(1)]
[ ]).reduce((x, xs) => [Sum(4)].concat([Sum(3), Sum(2), Sum(1)]))
// [Sum(4), Sum(3), Sum(2), Sum(1)]
Let me know if my inline evaluation is wrong, but I'd suspect we want concat
instead of cons
There seemed to be something dirty happening in these guys:
const cons = (x, xs) => [x].concat(xs)
const map = (f, xs) => foldr((acc, curr) => cons(f(curr), acc), [], xs)
I think its cos it wasn't calling concat on my actual Sum things, only on arrays?!?!
Anyways I ripped that crap out and used the map function from array and got it returning the correct answer. Just need to figure out how to get it into functions now.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
mempty()
?