Skip to content

Instantly share code, notes, and snippets.

@ktec
Last active January 30, 2017 22:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ktec/51fdcad2d5d002081f551a0c5b4b2b5c to your computer and use it in GitHub Desktop.
Save ktec/51fdcad2d5d002081f551a0c5b4b2b5c to your computer and use it in GitHub Desktop.
// 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)
@DrBoolean
Copy link

mempty()?

@DrBoolean
Copy link

DrBoolean commented Jan 30, 2017

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

@ktec
Copy link
Author

ktec commented Jan 30, 2017

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