Comments (12)
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 fold
s 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
toList
crock (List f, Semigroup s => f s ~> () -> s
) - Add
fold
pointfree. (fold : Foldable f, Semigroup s => f s -> s
)
from crocks.
Submitted PR#101 to address this issue.
from crocks.
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.
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.
@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.
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.
Merged PR#101. Will go out on next release.
Will close after conversation resolved.
from crocks.
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.
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.
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.
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.
Well typically, you build a List out by cons
ing, 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)
- import crocks lib to crocks.dev for using in browser console HOT 2
- README.md example confusion with `curry` HOT 8
- `yarn run setup` problem with `node-sass` dependency
- `yarn run docs:dev` fails with `ReferenceError: primordials is not defined`. Node v12.
- Updating the framework used for docs HOT 11
- Adding support for Symbol properties HOT 1
- Incomplete docs HOT 5
- Documentation for React Application HOT 3
- Upgrading Tape to 5.x results in these tests failing
- `getProp` of `null` value returns a `Just` HOT 4
- [QUESTION]: ~> syntax, "lifting" functions HOT 2
- dimap in arrow HOT 2
- How to unwrap Monads for return statements that expect a value? HOT 11
- Allow ReaderT to work with Fluture HOT 4
- Add local function to Reader and ReaderT
- Add getPropOrError to crocks HOT 6
- Async 'race' and 'all' cancellation after first rejection
- Distribute src as ES Modules HOT 2
- Add pointfree Pair to array (pairToArray) function
- Add the StateT monad
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from crocks.