Helpers
#
assigncrocks/helpers/assign
When working with Object
s, a common operation is to combine (2) of them. This
can be accomplished in crocks
by reaching for assign
. Unlike
the Object.assign
that ships with JavaScript, this assign
will combine
your Object
s into a new shallow copy of their merger. assign
only takes two
arguments and will overwrite keys present in the second argument with values
from the first. As with most of the crocks
Object
based functions, assign
will
omit any key-value pairs that are undefined
. Check out a related function
named defaultProps
that will only assign values that
are undefined
in the second argument.
#
binarycrocks/helpers/binary
With all the different functions out there in the real world, sometimes it is
nice to restrict them to a specific -arity to work with your all your wonderful
compositions. When you want to restrict any function of any arity to a simple
binary function. Just pass your function to binary
and you will get back a
curried, binary function that will only apply (2) arguments to the inner
function, ignoring any others. This works very well with functions
like Array.prototype.reduce
where you may only care about the first 2 arguments.
if you need to constrain to more than (2) arguments, then you will want to reach
for nAry
. binary
is basically syntactic sugar for nAry(2, fn)
.
Also related is unary
, which constrains to (1) argument.
#
composecrocks/helpers/compose
While the composeB
can be used to create a
composition of two functions, there are times when you want to compose an entire
flow together. That is where compose
is useful. With compose
you can create
a right-to-left composition of functions. It will return you a function that
represents your flow. crocks
provides a means to build compostions using a
left-to-right style in the form of pipe
.
- Source
- Runkit
#
composeKcrocks/helpers/composeK
There are many times that, when working with the various crocks
, our flows are
just a series of chain
s. Due to some neat properties with types that provide
a chain
function, you can remove some boilerplate by reaching for composeK
.
Just pass it the functions you would normally pass to chain
and it will do all
the boring hook up for you. Just like compose
, functions are applied
right-to-left, so you can turn this:
- Source
- Runkit
into the more abbreviated form:
- Source
- Runkit
As demonstrated in the above example, this function more closely resembles flows
that are using a more pointfree style of coding. As with the other composition
functions in crocks
, a pipeK
function is provided for flows that
make more sense expressed in a left-to-right style.
#
composePcrocks/helpers/composeP
When working with Promise
s, it is common place to create chains on
a Promise
's then
function. Doing this involves a lot of boilerplate and
forces you into a fluent style, whether you want to be or not. Using composeP
you
have the option to compose a series of Promise
returning functions like you
would any other function composition, in a right-to-left fashion.
Due to the nature of the then
function, only the head of your composition
needs to return a Promise
. This will create a function that takes a value,
which is passed through your chain, returning a Promise
which can be extended.
This is only a then
chain, it does not do anything with the catch
function.
If you would like to provide your functions in a left-to-right manner, check
out pipeP.
- Source
- Runkit
#
composeScrocks/helpers/composeS
When working with things like Arrow
and Star
there will come a point when
you would like to compose them like you would any Function
. That is
where composeS
comes in handy. Just pass it the Semigroupoid
s you want to compose
and it will give you back a new Semigroupoid
of the same type with all of the
underlying functions composed and ready to be run.
Like compose
, composeS
composes the functions in a right-to-left
fashion. If you would like to represent your flow in a more left-to-right manner,
then pipeS
is provided for such things.
- Source
- Runkit
#
currycrocks/helpers/curry
Pass this function a function and it will return you a function that can be
called in any form that you require until all arguments have been provided. For
example if you pass a function: f : (a, b, c) -> d
you get back a function
that can be called in any combination, such as: f(x, y, z)
, f(x)(y)(z)
,
f(x, y)(z)
, or even f(x)(y, z)
. That is to say, this function fulfills the role
of both curry and uncurry, returning a function that can be used as a curried
function, an uncurried function, or any combination of argument applications in
between. The returned function has 2^(n-1)
type signatures, where n
is the
number of parameters.
- Source
- Runkit
An important caveat when using curry
with functions containing optional parameters,
is that the defaults are applied immediately, reducing the number of partial
applications to just the number of required parameters. Adding optional parameters
to functions may not be a good choice if the intention is to use them with curry
,
as the ability to change the defaults is lost. Parameters are applied up until the
first optional parameter, at which point subsequent parameters either receive the
declared default or go undefined.
- Source
- Runkit
#
defaultPropscrocks/helpers/defaultProps
Picture this, you have an Object
and you want to make sure that some
properties are set with a given default value. When the need for this type of
operation presents itself, defaultProps
can come to your aid. Just pass it
an Object
that defines your defaults and then the Object
your want to default
those props on. If a key that is present on the defaults Object
is not defined
on your data, then the default value will be used. Otherwise, the value from
your data will be used instead. You could just apply flip
to
the assign
function and get the same result, but having a function
named defaultProps
may be easier to read in code. As with most Object
related
functions in crocks
, defaultProps
will return you a shallow copy of the
result and not include any undefined
values in either Object
.
#
defaultTocrocks/helpers/defaultTo
With things like null
, undefined
and NaN
showing up all over the place, it
can be hard to keep your expected types inline without resorting to nesting in
a Maybe
with functions like safe
. If you want to specifically guard
for null
, undefined
and NaN
and get things defaulted into the expected
type, then defaultTo
should work for you. Just pass it what you would like
your default value to be and then the value you want guarded, and you will get
back either the default or the passed value, depending on if the passed value
is null
, undefined
or NaN
. While this is JavaScript and you can return
anything, it is suggested to stick to the signature and only let a
s through.
As a b
can be an a
as well.
#
fromPairscrocks/helpers/fromPairs
As an inverse to toPairs
, fromPairs
takes either
an Array
or List
of key-value Pair
s and constructs an Object
from it.
The Pair
must contain a String
in the fst
and any type of value in
the snd
. The fst
will become the key for the value in the snd
. All
primitive values are copied into the new Object
, while non-primitives are
references to the original. If you provide an undefined
values for the second,
that Pair
will not be represented in the resulting Object
. Also, when if
multiple keys share the same name, that last value will be moved over.
#
getPathOrcrocks/helpers/getPathOr
While getPropOr
is good for simple, single-level
structures, there may come a time when you have to work with nested POJOs or
Arrays. When you run into this situation, just pull in getPathOr
, which was
previously called propPathOr
, and pass it a left-to-right traversal path of
keys, indices or a combination of both (gross...but possible). This will kick
you back a function that behaves just like getPropOr
. You pass
it some data, and it will attempt to resolve your provided path. If the path is
valid, it will return the value. But if at any point that path "breaks" it will
give you back the default value.
- Source
- Runkit
#
getPropOrcrocks/helpers/getPropOr
Reach for getPropOr
, previously known as propOr
, when you want some safety
around pulling a value out of an Object or Array with a single key or
index. Well, as long as you are working with non-nested data that is. Just
tell getPropOr
either the key or index you are interested in, and you will get
back a function that will take anything and return the wrapped value if the
key/index is defined. If the key/index is not defined however, you will get back
the provided default value.
- Source
- Runkit
#
liftA2crocks/helpers/liftA2
#
liftA3crocks/helpers/liftA3
Ever see yourself wanting to map
a binary or trinary function, but map
only
allows unary functions? Both of these functions allow you to pass in your
function as well as the number of Applicative
s (containers that provide
both of
and ap
functions) you need to get the mapping you are looking for.
#
liftNcrocks/helpers/liftN
While liftA2
and liftA3
will handle a majority of
the functions we tend to encounter, many cases arise when we want to deal with
functions of a greater arity. In those cases, liftN
will allow the lifting of
function of any size arity.
liftN
takes a Number
that specifies the arity of the function to be lifted,
followed by the function itself and finally the required number
of Applicative
instances of the same type to be applied to the target
function.
In most cases, there is no need to explicitly curry the target function. This
function operates in the same vein as nAry
and as such manually
curried functions (i.e. x => y => x + y
) will need to be explicitly curried
using curry
to ensure proper application of the arguments.
- Source
- Runkit
#
mapPropscrocks/helpers/mapProps
Would like to map specific keys in an Object with a specific function? Just
bring in mapProps
and pass it an Object
with the functions you want to apply
on the keys you want them associated to. When the resulting function receives
an Object
, it will return a new Object
with the keys mapped according to the
mapping functions. All keys from the original Object
that do not exist in
the mapping Object
will still exist untouched, but the keys with mapping
functions with now contain the result of applying the original value to the
provided mapping function.
mapProps
also allows for mapping on nested Object
s for times when the shape
of the original Object
is know.
- Source
- Runkit
#
mapReducecrocks/helpers/mapReduce
Sometimes you need the power provided by mreduceMap
but you do
not have a Monoid
to lift into. mapReduce
provides the same power, but with
the flexibility of using functions to lift and combine. mapReduce
takes a
unary mapping function, a binary reduction function, the initial value and
finally a Foldable
structure of data. Once all arguments are provided,
mapReduce
folds the provided data, by mapping each value through your mapping
function, before sending it to the second argument of your reduction function.
- Source
- Runkit
#
mconcatcrocks/helpers/mconcat
#
mreducecrocks/helpers/mreduce
These two functions are very handy for combining an entire List
or Array
of
values by providing a Monoid
and your collection of
values. The difference between the two is that mconcat
returns the result
inside the Monoid
used to combine them.
Where mreduce
returns the bare value itself.
#
mconcatMapcrocks/helpers/mconcatMap
#
mreduceMapcrocks/helpers/mreduceMap
There comes a time where the values you have in a List
or an Array
are not
in the type that is needed for the Monoid
you want to
combine with. These two functions can be used to map
some transforming
function from a given type into the type needed for
the Monoid
. In essence, this function will run each value through
the function before it lifts the value into the Monoid
,
before concat
is applied. The difference between the two is
that mconcatMap
returns the result inside the Monoid
used
to combine them. Where mreduceMap
returns the bare value itself.
#
nArycrocks/helpers/nAry
When using functions like Math.max
or Object.assign
that take as many
arguments as you can throw at them, it makes it hard to curry
them in a
reasonable manner. nAry
can make things a little nicer for functions like
that. It can also be put to good use to limit a given function to a desired
number of arguments to avoid accidentally supplying default arguments when you
do not what them applied. First pass nAry
the number of arguments you wish to
limit the function to and then the function you wish to limit. nAry
will give
you back a curried function that will only apply the specified number of
arguments to the inner function. Unary and binary functions are so common
that crocks
provides specific functions for those
cases: unary
and binary
.
#
objOfcrocks/helpers/objOf
If you ever find yourself in a situation where you have a key and a value and
just want to combine the two into an Object
, then it sounds like objOf
is
the function for you. Just pass it a String
for the key and any type of value,
and you'll get back an Object
that is composed of those two. If you find
yourself constantly concatenating the result of this function into
another Object
, you may want to use assoc
instead.
#
omitcrocks/helpers/omit
Sometimes you just want to strip Object
s of unwanted properties by key.
Using omit
will help you get that done. Just pass it a Foldable
structure
with a series of String
s as keys and then pass it an Object
and you will
get back not only a shallow copy, but also an Object
free of any of those
pesky undefined
values. You can think of omit
as a way to black-list or
reject Object
properties based on key names. This function ignores inherited
properties and should only be used with POJOs. If you want to filter or
white-list properties rather than reject them, take a look at pick
.
#
oncecrocks/helpers/once
There are times in JavaScript development where you only want to call a function
once and memo-ize the first result for every subsequent call to that function.
Just pass the function you want guarded to once
and you will get back a
function with the expected guarantees.
#
partialcrocks/helpers/partial
There are many times when using functions from non-functional libraries or from
built-in JS functions, where it does not make sense to wrap it in
a curry
. You just want to partially apply some arguments to it and
get back a function ready to take the rest. That is a perfect opportunity to
use partial
. Just pass a function as the first argument and then apply any
other arguments to it. You will get back a curried function that is ready to
accept the rest of the arguments.
- Source
- Runkit
#
pickcrocks/helpers/pick
When dealing with Object
s, sometimes it is necessary to only let some of the
key-value pairs on an object through. Think of pick
as a sort of white-list or
filter for Object
properties. Pass it a Foldable
structure of String
s that
are the keys you would like to pick off of your Object
. This will give you
back a shallow copy of the key-value pairs you specified. This function will
ignore inherited properties and should only be used with POJOs.
Any undefined
values will not be copied over, although null
values are
allowed. For black-listing properties, have a look at omit
.
#
pipecrocks/helpers/pipe
Similar to compose
, pipe
allows for the composition of
functions, but takes its functions in a left-to-right fashion, which is the
opposite of compose
. Just like compose
, pipe
will return a new function that represents the composed flow.
- Source
- Runkit
#
pipeKcrocks/helpers/pipeK
Like composeK
, you can remove much of the boilerplate when
chaining together a series of functions with the signature:
Chain m => a -> m b
. The difference between the two functions is, while
composeK
is right-to-left, pipeK
is the opposite, taking its
functions left-to-right.
- Source
- Runkit
#
pipePcrocks/helpers/pipeP
Like the composeP
function, pipeP
will let you remove the
standard boilerplate that comes with working with Promise
chains. The only
difference between pipeP
and composeP
is that it takes its
functions in a left-to-right order:
- Source
- Runkit
#
pipeScrocks/helpers/pipeS
While Star
s and Arrow
s come in very handy at times, the only thing that
could make them better is to compose them. With pipeS
you can do just that
with any Semigroupoid
. Just like with composeS
, you just pass
it Semigroupoid
s of the same type and you will get back
another Semigroupoid
with them all composed together. The only difference
between the two, is that pipeS
composes in a left-to-right fashion,
while composeS
does the opposite.
- Source
- Runkit
#
setPathcrocks/helpers/setPath
Used to set a value on a deeply nested Object
, setPath
will traverse down
a path and set the a the final property to the provided value. setPath
returns
the an Object
/Array
with the modification and does not alter the
original Object
/Array
along the path.
The provided path can be a mixture of either Integer
s or String
s to allow
for traversing through both Array
s and Object
s. When an Integer
zero or
greater is provided it will treat that portion as an Array
while String
s are
used to reference through Object
s. If at any point in the provided
a NaN
, undefined
or null
values is encountered, a
new Object
/Array
will be created.
- Source
- Runkit
#
setPropcrocks/helpers/setProp
Used to set a given value for a specific key or index of
an Object
or Array
. setProp
, previously called assoc
, takes either
a String
or Integer
value as its first argument and a value of any type as
its second. The third parameter is dependent of the type of the first argument.
When a String
is provided, the third argument must be an Object
. Otherwise
if the first argument is an Integer
zero or greater, then the third must be
an Array
.
setProp
will return a new instance of either Object
or Array
with the
addition applied. When the value exists on the provided object, then the value
will overwritten. If the value does not exist then it will be added to the
resulting structure. In the case of Array
, the value will be added to the
provided index, leaving undefined
values, resulting in a sparse Array
.
- Source
- Runkit
#
tapcrocks/helpers/tap
It is hard knowing what is going on inside of some of these ADTs or your
wonderful function compositions. Debugging can get messy when you need to insert
a side-effect into your flow for introspection purposes. With tap
, you can
intervene in your otherwise pristine flow and make sure that the original value
is passed along to the next step of your flow. This function does not guarantee
immutability for reference types (Objects
, Arrays
, etc), you will need to
exercise some discipline here to not mutate.
#
tryCatchcrocks/Result/tryCatch
Typical try-catch blocks are very imperative in their usage. This tryCatch
function
provides a means of capturing that imperative nature in a simple declarative
style. Pass it a function that could fail and it will return you another function
wrapping the first function. When called, the new function will either return the
result in a Result.Ok
if everything was good, or an error wrapped in
an Result.Err
if it fails.
#
unarycrocks/helpers/unary
If you every need to lock down a given function to just one argument, then look
no further than unary
. Just pass it a function of any arity, and you will get
back another function that will only apply (1) argument to given function, no
matter what is passed to it. unary
is just syntactic sugar around
nAry
in the form of nAry(1, fn)
as it is such a common case.
Another common case is binary
which, as the name implies, only
applies (2) arguments to a given function.
#
unitcrocks/helpers/unit
While it seems like just a simple function, unit
can be used for a number of
things. A common use for it is as a default noop
as it is a function that does
nothing and returns undefined
. You can also use it in a pointed fashion to
represent some special value for a given type. This pointed use is the heart and
soul of the infamous Maybe
type.
#
unsetPathcrocks/helpers/unsetPath
Used to remove a property or index on a deeply nested Object
/Array
.
unsetPath
, previously called dissoc
, will return a new instance with the
property or index removed.
The provided path can be a mixture of either Positive Integer
s or String
s to
allow for traversing through both Array
s and Object
s. When an Integer
is
provided it will treat that portion as an Array
while String
s are used to
reference through Object
s.
- Source
- Runkit
#
unsetPropcrocks/helpers/unsetProp
unsetProp
is a binary function that takes either a property name or an index
as its first argument. Which specifies what should be removed, or "unset", from
the Object
or Array
provided as the second argument. If the value provided
for the second argument is not an Object
or Array
, then the value provided
is echoed back as the result.
The first argument must be either a non-empty String
or
positive Integer
. A String
should be provided when working with
an Object
, while Array
s require an Integer
. unsetProp
will return a new
instance of either the Object
or Array
, sans the key or index.
- Source
- Runkit