Skip to content

Instantly share code, notes, and snippets.

@coodoo
Last active June 18, 2017 06:15
Show Gist options
  • Save coodoo/1eef2704b976362503b83daac0281790 to your computer and use it in GitHub Desktop.
Save coodoo/1eef2704b976362503b83daac0281790 to your computer and use it in GitHub Desktop.
練習實作一支 Map type 與其身上多支指令,例如 map(), reduce(), foldMap() 等...
const Mapp = val => ({
val,
// {a: 'aa', b: 'bb'}
// f :: v -> value
map: f => {
const o = {}
// let resultArr = Object.keys(val).map((key, idx) => ({ [key]: f(val[key]) })) // 錯的,會變成[{}, {}]
Object.keys(val).map((key, idx) => o[key] = f(val[key]) )
// return o // 錯的,要包回 Mapp
return Mapp(o)
},
// f :: (acc, itm) -> value
reduce: (f, acc) => {
return Object.keys(val).reduce( (acc, key) => f(acc, val[key]), acc )
},
concat: ({val: y}) => {
let arr = Object.keys(val)
let brr = arr.map( key => val[key].concat(y[key]) )
return brr
},
fold: (empty) => {
return this.foldMap(x => x, empty)
},
foldMap: (f, empty) => {
return empty != null
? this.reduce((acc, x) => acc.concat(f(x)), empty)
: this.reduce((acc, x) => acc.concat(f(x)))
},
sequence: point => {
return this.traverse(point, x => x)
},
traverse: (point, f) => {
return this.reduce((acc, v, k) =>
f(v, k).map(x => y => y.merge({[k]: x})).ap(acc), point(this.empty))
},
})
console.log( Mapp.of({a: 1, b: 2}).map( v => v*2 ) ) // [ { a: 2 }, { b: 4 } ]
console.log( Mapp.of({a: 1, b: 2}).reduce( (acc, itm) => acc+itm, 100 ) ) // 103
@rayshih
Copy link

rayshih commented Jun 18, 2017

我也來練習一下:

const Map = (val) => ({
  fmap: f => Map(Object.keys(val)
    .map(k => ({k, v: f(val[k])}))
    .reduce((acc, {k, v}) => ({...acc, [k]: v}), {})),
  extract: () => val
})

const v = Map({a: 1, b: 2})
console.log(
  v.fmap(a => a + 1)
   .fmap(a => a * a)
   .extract()
) // {a: 4, b: 9}

tested in babel try it out

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