Git Product home page Git Product logo

Comments (12)

evilsoft avatar evilsoft commented on May 14, 2024

Alrighty, going to redefine this after thinking about it for a second.

I would be nice to have a way to fold a List or Array of semigroups down and extract from the container.

As folds are called reduce in JS, I am thinking we should add a fold function to List that will fold down a list of Semigroups and extract the Semigroup from the List, as folds do. Also this will create the need for a fold pointfree function that can accept any foldable structure. So you can do things like:

const {
  Pred, compose, contramap, fold,
  map, isNumber, prop, option,
  reverseApply, runWith
} = crocks

// defProp : a -> String -> Object -> a
const defProp = curry(
  (def, key) => compose(option(def), prop(key))
)

// defNotFound : String -> Object -> String | a
const defNotFound =
  defProp('Not Found')

// preds : [ Pred Object ]
const preds =
  map(reverseApply(Pred(isNumber)), [
    contramap(defNotFound('a')),
    contramap(defNotFound('b')),
    contramap(defNotFound('c'))
  ])

// buildValidator : [ Pred a ] -> b -> Boolean
const buildValidator =
  compose(flip(runWith), fold)

// isValid : a -> Boolean
const isValid =
  buildValidator(preds)

isValid({ a: 34, b: 10, c: 3 }) // true
isValid({ b: 10, c: 3 }) // false
isValid({ a: 34, b: 'ten', c: 3 }) // false
  • Add fold to List crock (List f, Semigroup s => f s ~> () -> s)
  • Add fold pointfree. (fold : Foldable f, Semigroup s => f s -> s)

from crocks.

evilsoft avatar evilsoft commented on May 14, 2024

Submitted PR#101 to address this issue.

from crocks.

rstegg avatar rstegg commented on May 14, 2024

What are your thoughts on a foldWith for completeness?

List([1,2,3,4,5]).foldWith(add2) // [3,4,...]

implementation would be something like:

  List m => m a ~> (a -> b) -> b
  function foldWith(fn) {
    if(!isFunction(fn)) {
      throw new TypeError('List.foldWith: Function required')
    }

    return xs.map(fn) 
  }

from crocks.

rstegg avatar rstegg commented on May 14, 2024

I realize this is adding a lot to a single type; but doing some 👀 around, I found that List is very "immutableJS" territory, see: https://facebook.github.io/immutable-js/docs/#/List [i did not really look into immutablejs until now. if you are already aware of the implementation which immutable provides, please ignore this]

from crocks.

evilsoft avatar evilsoft commented on May 14, 2024

@rstegg That is a valid point. I thought about adding foldMap. And really foldMap in its implementation is really just reduce. Notice how you are returning an array, which is just the underlying implementation of List in its current state. So because it is maintaining structure, all you really did there is implement map and extract to an Array, which IMO does not add value. A fold as I understand it, take a collection (one or many) applies some function to it, to combine all elements into a single value (usually). Which is what reduce is in JS.

The reason why we do not need a combining function for this fold is because we have the Semigroup constraint on the underlying values. So we will use the built in function concat which is on every semigroup to do the combination.

What you implemented can easily be expressed as a function to reduce that uses an Array as its initial value, and concats each item in the List to it. I really do not see the need to add this as it may be confusing to have this option. But I am open to argument on this one.

from crocks.

evilsoft avatar evilsoft commented on May 14, 2024

I would say that List is the domain of all functional libs and paradigms. It is the fundamental/canonical representation/expression of determinism we have. Now one thing my List lacks (that will be rectified soon) is the constraint that all elements MUST be of the same type. Once we have that I would say that this List can prove to be very useful.

I am curious what would be gained by providing that robust API? A lot of those functions make sense in an imperative environment (shift/unshift as to cons/head/tail) . And with the improvements to Array based functions, you should be able to get those more imperative bits with your standard JS Array.

from crocks.

evilsoft avatar evilsoft commented on May 14, 2024

Merged PR#101. Will go out on next release.
Will close after conversation resolved.

from crocks.

evilsoft avatar evilsoft commented on May 14, 2024

Now that said, your provided implementation does not add much value.
Now if we had a Semigroup constraint on the return of the Mapping function THEN we are in business IMO.

List m, Semigroup s => m a ~> (a -> s b) -> s b

Then we could do things like:

const { List, Sum, foldMap, concat, reduce } = crocks

const ar =
  List
    .fromArray([ 1, 2, 3 ])
   .foldMap(Sum)
// => Sum(6)

What do you think about that?

from crocks.

evilsoft avatar evilsoft commented on May 14, 2024

While that seems like a good idea one thing that comes to mind is that we already have mconcat and mconcatMap which already takes either a List or Array (for this exact use case) so we can do this to get the same thing as above:

const { Sum, mconcat } = crocks

const data =
  [ 1, 2, 3 ]

const sumList =
  mconcat(Sum)

sumList(data)
// => Sum(6)

sumList(List.fromArray(data)
// => Sum(6)

The only bummer, is that mconcat and family need to recognize String and Array as proper Monoids that way you can make single level flatten like:

const data =
[ [ 1, 2], [ 3 ], [ 4, 5 ] ]

const flatten =
  mconcat(Array)

flatten(data)
// => [ 1, 2, 3, 4, 5 ]

from crocks.

evilsoft avatar evilsoft commented on May 14, 2024

I think we would get better reusability if instead, we just focus on getting the mconcat family to fully honor the Monoidal qualities of Array and String.

from crocks.

rstegg avatar rstegg commented on May 14, 2024

All good points, in my opinion I like not having to wrap my data in an array (e.g. List(1,2,3,4) => List [1,2,3,4]), because that just, to me, feels like an extra thing to remember about this implementation of List and one that I really think is great in immutablejs.

Back on foldMap, that is correct I did not think of how many ways there could be to solve one problem, and adding another solution should seem like a waste of time.

I think this has solved any problems we've had with fold now, 👍 to closing this issue.

from crocks.

evilsoft avatar evilsoft commented on May 14, 2024

Well typically, you build a List out by consing, or generating it, then fold it down in to a result. So passing an Array into it, is just for convince if you NEED to be in a List. Soon, we will have a lot of functions that just work on Arrays like any other datatype in crocks.

Closing!

from crocks.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.