Helpers
assign#
crocks/helpers/assign
When working with Objects, 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 Objects 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.
binary#
crocks/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.
compose#
crocks/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
composeK#
crocks/helpers/composeK
There are many times that, when working with the various crocks, our flows are
just a series of chains. 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.
composeP#
crocks/helpers/composeP
When working with Promises, 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
composeS#
crocks/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 Semigroupoids 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
curry#
crocks/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
defaultProps#
crocks/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.
defaultTo#
crocks/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 as through.
As a b can be an a as well.
fromPairs#
crocks/helpers/fromPairs
As an inverse to toPairs, fromPairs takes either
an Array or List of key-value Pairs 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.
getPathOr#
crocks/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
getPropOr#
crocks/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
liftA2#
crocks/helpers/liftA2
liftA3#
crocks/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 Applicatives (containers that provide
both of and ap functions) you need to get the mapping you are looking for.
liftN#
crocks/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
mapProps#
crocks/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 Objects for times when the shape
of the original Object is know.
- Source
- Runkit
mapReduce#
crocks/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
mconcat#
crocks/helpers/mconcat
mreduce#
crocks/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.
mconcatMap#
crocks/helpers/mconcatMap
mreduceMap#
crocks/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.
nAry#
crocks/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.
objOf#
crocks/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.
omit#
crocks/helpers/omit
Sometimes you just want to strip Objects of unwanted properties by key.
Using omit will help you get that done. Just pass it a Foldable structure
with a series of Strings 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.
once#
crocks/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.
partial#
crocks/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
pick#
crocks/helpers/pick
When dealing with Objects, 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 Strings 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.
pipe#
crocks/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
pipeK#
crocks/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
pipeP#
crocks/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
pipeS#
crocks/helpers/pipeS
While Stars and Arrows 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 Semigroupoids 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
setPath#
crocks/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 Integers or Strings to allow
for traversing through both Arrays and Objects. When an Integer zero or
greater is provided it will treat that portion as an Array while Strings are
used to reference through Objects. If at any point in the provided
a NaN, undefined or null values is encountered, a
new Object/Array will be created.
- Source
- Runkit
setProp#
crocks/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
tap#
crocks/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.
tryCatch#
crocks/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.
unary#
crocks/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.
unit#
crocks/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.
unsetPath#
crocks/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 Integers or Strings to
allow for traversing through both Arrays and Objects. When an Integer is
provided it will treat that portion as an Array while Strings are used to
reference through Objects.
- Source
- Runkit
unsetProp#
crocks/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 Arrays require an Integer. unsetProp will return a new
instance of either the Object or Array, sans the key or index.
- Source
- Runkit