evilsoft / crocks

A collection of well known Algebraic Data Types for your utter enjoyment.
https://crocks.dev
ISC License
1.59k stars 102 forks source link

Allow `String` and `Array` constructors anywhere a Monoid is accepted #105

Open evilsoft opened 7 years ago

evilsoft commented 7 years ago

So there is no reason we cannot just accept String and Array JS Constructors as Monoid. They will need to be implemented in the following places:

dalefrancis88 commented 5 years ago

Hey, There is a small issue with Array having two constructors, one of which is when taking a number this'll define the length of the Array.

I have an idea but not sure if it's the best, what are your thoughts?

https://repl.it/@DaleFrancis/String-Array-Monoid

evilsoft commented 5 years ago

Hmmm. You may wanna wait on this until I finish up the changes I am doing to Writer, have some ideas about getting the empty for JS Types.

Also this core function will need to be changes to remove the foldWith and the compose we should do it in place to avoid the addition of stack frames. Was thinking something like:

const fl = require('crocks/core/flNames')

// comming soon in core
const primatives = T => ({
  ['String']: () => '',
  ['Array']: () => []
})[T.name]

// export coming soon in core
const getEmpty = T =>
  T[fl.empty] || T.empty || primatives(T)

// core implementation, all validation happens in implementing functions
// no errors or composition or anything here.
function _mconcatMap(Rep, fn, xs) {
  const empty = getEmpty(Rep)

  const M = Rep === Array
    ? x => [ x ]
    : Rep

  return xs.reduce(
    (acc, x) => acc.concat(M(fn(x))),
    empty()
  )
}

// Example
const { List, curry } = require('crocks')

const mconcatMap =
  curry(_mconcatMap)

const data =
  List.fromArray([ 1, 3, 5, 6 ])

const mapListToArray = curry(
  fn => mconcatMap(Array, fn)
)
evilsoft commented 5 years ago

And I think we may have to dispatch concat to one of the core files, string or array. We want to put an error in the case of something like:

mconcat(String, [ 1, 2, 3, 4 ])
//=> '1234'

it should throw an error instead of doing the default concat because of Semigroup laws. they need to be instances of the same type.

dalefrancis88 commented 5 years ago

Cool we seem to be on the same page here, albeit yours being nicer, i'm glad that's the case.

Happy to take this on once the new things are in core