Skip to content

Commit

Permalink
Merge cdcd83f into d670c2b
Browse files Browse the repository at this point in the history
  • Loading branch information
evilsoft committed Apr 18, 2019
2 parents d670c2b + cdcd83f commit 6b1b61c
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 98 deletions.
10 changes: 5 additions & 5 deletions docs/src/pages/docs/crocks/Equiv.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ import Equiv from 'crocks/Equiv'
import compareWith from 'crocks/pointfree/compareWith'
import equals from 'crocks/pointfree/equals'
import isSameType from 'crocks/predicates/isSameType'
import propOr from 'crocks/helpers/propOr'
import getPropOr from 'crocks/helpers/getPropOr'

// objLength :: Object -> Number
const objLength =
Expand All @@ -177,7 +177,7 @@ const length =

// sameType :: Equiv a a
const sameTypeProp = key =>
sameType.contramap(propOr(null, key))
sameType.contramap(getPropOr(null, key))

// run :: Equiv Object Object
const run = compareWith(
Expand Down Expand Up @@ -278,7 +278,7 @@ import Equiv from 'crocks/Equiv'

import compose from 'crocks/helpers/compose'
import equals from 'crocks/pointfree/equals'
import propOr from 'crocks/helpers/propOr'
import getPropOr from 'crocks/helpers/getPropOr'

// toLower :: String -> String
const toLower =
Expand All @@ -290,11 +290,11 @@ const length =

// lowerName :: Object -> String
const lowerName =
compose(toLower, propOr('', 'name'))
compose(toLower, getPropOr('', 'name'))

// itemsLen :: Object -> Number
const itemsLen =
compose(length, propOr('', 'items'))
compose(length, getPropOr('', 'items'))

// eq :: Equiv a a
const eq =
Expand Down
10 changes: 5 additions & 5 deletions docs/src/pages/docs/crocks/Pred.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ This implementation of `Pred` was heavily inspired by [this article](https://med
import Pred from 'crocks/Pred'

import isNumber from 'crocks/predicates/isNumber'
import propOr from 'crocks/helpers/propOr'
import getPropOr from 'crocks/helpers/getPropOr'
import filter from 'crocks/pointfree/filter'

// largeNumber :: Pred Number
Expand All @@ -45,7 +45,7 @@ const largeNumber =
// largeItem :: Pred Object
const largeItem =
largeNumber
.contramap(propOr(null, 'item'))
.contramap(getPropOr(null, 'item'))

largeNumber
.runWith(45)
Expand Down Expand Up @@ -266,12 +266,12 @@ mapping the input to now accept the type of the input of the given function.
```javascript
import Pred from 'crocks/Pred'
import contramap from 'crocks/pointfree/contramap'
import propOr from 'crocks/helpers/propOr'
import getPropOr from 'crocks/helpers/getPropOr'

// Length :: String | Function | Array
// length :: Length -> Number
const length =
propOr(0, 'length')
getPropOr(0, 'length')

// gt5 :: Pred Number
const gt5 =
Expand All @@ -283,7 +283,7 @@ const validLength =

// validItemLength :: Pred Object
const validItemLength =
contramap(propOr(null, 'item'), validLength)
contramap(getPropOr(null, 'item'), validLength)

gt5
.runWith(5)
Expand Down
16 changes: 8 additions & 8 deletions docs/src/pages/docs/crocks/State.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ import State from 'crocks/State'

import compose from 'crocks/helpers/compose'
import objOf from 'crocks/helpers/objOf'
import propOr from 'crocks/helpers/propOr'
import getPropOr from 'crocks/helpers/getPropOr'

const { get } = State

Expand All @@ -354,7 +354,7 @@ const add =

// getNum :: State Object Number
const getNum =
get(propOr(0, 'num'))
get(getPropOr(0, 'num'))

getNum
.map(add(10))
Expand Down Expand Up @@ -399,7 +399,7 @@ instances' resultants.
import State from 'crocks/State'

import setProp from 'crocks/helpers/setProp'
import propOr from 'crocks/helpers/propOr'
import getPropOr from 'crocks/helpers/getPropOr'

const { get, modify } = State

Expand All @@ -422,7 +422,7 @@ const round =

// getKey :: String -> State Object Number
const getKey = key =>
get(propOr(0, key))
get(getPropOr(0, key))

// updateKey :: String -> a -> State Object ()
const updateKey = key => val =>
Expand Down Expand Up @@ -552,7 +552,7 @@ State s a ~> s -> a
`State` is a lazy datatype that requires a value for it's state portion to
be run. A given `State` instance provides an `evalWith` method that accepts a
value to run the instance with. The value must be a member of the type that the
given `State` instance is fixed to in it's state portion, `s`.
given `State` instance is fixed to in its state portion, `s`.

When called, `evalWith` will run the state transition with the given value as
the initial state and will return the resulting resultant discarding the state
Expand All @@ -565,7 +565,7 @@ import concat from 'crocks/pointfree/concat'
import flip from 'crocks/combinators/flip'
import liftA2 from 'crocks/helpers/liftA2'
import map from 'crocks/pointfree/map'
import propOr from 'crocks/helpers/propOr'
import getPropOr from 'crocks/helpers/getPropOr'

const { get } = State

Expand All @@ -576,11 +576,11 @@ const name = {

// getLast :: State Object String
const getFirst =
get(propOr('', 'first'))
get(getPropOr('', 'first'))

// getLast :: State Object String
const getLast =
get(propOr('', 'last'))
get(getPropOr('', 'last'))

// inner :: Functor f => f a -> f [ a ]
const inner =
Expand Down
109 changes: 55 additions & 54 deletions docs/src/pages/docs/functions/helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "Helpers"
description: "Helper functions"
layout: "notopic"
functions: ["assign", "assoc", "binary", "compose", "composek", "composep", "composes", "curry", "defaultprops", "defaultto", "dissoc", "frompairs", "lifta2", "lifta3", "liftn", "mapprops", "mapreduce", "mconcat", "mconcatmap", "mreduce", "mreducemap", "nary", "objof", "omit", "once", "partial", "pick", "pipe", "pipek", "pipep", "pipes", "propor", "proppathor", "setpath", "setprop", "tap", "unary", "unit", "unsetpath", "unsetprop"]
functions: ["assign", "assoc", "binary", "compose", "composek", "composep", "composes", "curry", "defaultprops", "defaultto", "dissoc", "frompairs", "getpropor", "lifta2", "lifta3", "liftn", "mapprops", "mapreduce", "mconcat", "mconcatmap", "mreduce", "mreducemap", "nary", "objof", "omit", "once", "partial", "pick", "pipe", "pipek", "pipep", "pipes", "propor", "proppathor", "setpath", "setprop", "tap", "unary", "unit", "unsetpath", "unsetprop"]
weight: 20
---

Expand Down Expand Up @@ -340,6 +340,52 @@ 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.


#### getPropOr

`crocks/helpers/getPropOr`

```haskell
getPropOr :: a -> (String | Integer) -> b -> a
```

If you want some safety around pulling a value out of an Object or Array with a
single key or index, you can always reach for `getPropOr`. 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.

```javascript
import getPropOr from 'crocks/helpers/getPropOr'

const data = {
foo: 'bar',
null: null,
nan: NaN,
undef: undefined
}

// def :: (String | Integer) -> a -> b
const def =
getPropOr('default')

def('foo', data)
//=> "bar"

def('null', data)
//=> null

def('nan', data)
//=> NaN

def('baz', data)
//=> "default"

def('undef', data)
//=> "default"
```

#### liftA2

`crocks/helpers/liftA2`
Expand Down Expand Up @@ -916,51 +962,6 @@ flow('string', 100)
// => Nothing
```

#### propOr

`crocks/helpers/propOr`

```haskell
propOr :: a -> (String | Integer) -> b -> c
```

If you want some safety around pulling a value out of an Object or Array with a
single key or index, you can always reach for `propOr`. Well, as long as you are
working with non-nested data that is. Just tell `propOr` 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.

```javascript
import propOr from 'crocks/helpers/propOr'

const data = {
foo: 'bar',
null: null,
nan: NaN,
undef: undefined
}

// def :: (String | Integer) -> a -> b
const def =
propOr('default')

def('foo', data)
//=> "bar"

def('null', data)
//=> null

def('nan', data)
//=> NaN

def('baz', data)
//=> "default"

def('undef', data)
//=> "default"
```

#### propPathOr

`crocks/helpers/propPathOr`
Expand All @@ -969,14 +970,14 @@ def('undef', data)
propPathOr :: Foldable f => a -> f (String | Integer) -> b -> c
```

While [`propOr`](#propor) 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 `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 [`propOr`](#propor). 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.
While [`getPropOr`](#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 `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`](#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.

```javascript
import propPathOr from 'crocks/helpers/propPathOr'
Expand Down
5 changes: 3 additions & 2 deletions docs/src/pages/docs/functions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ need to account for for the rest of your flow.
| [`fanout`][fanout] | `(a -> b) -> (a -> c) -> (a -> Pair b c)` | `crocks/Pair/fanout` |
| [`find`][find] | <code>Foldable f => ((a -> Boolean) &#124; Pred) -> f a -> Maybe a</code> | `crocks/Maybe/find` |
| [`fromPairs`][frompairs] | `Foldable f => f (Pair String a) -> Object` | `crocks/helpers/fromPairs` |
| [`getPropOr`][getpropor] | <code>a -> (String &#124; Integer) -> b -> c</code> | `crocks/helpers/getPropOr` |
| [`liftA2`][lifta2] | `Applicative m => (a -> b -> c) -> m a -> m b -> m c` | `crocks/helpers/liftA2` |
| [`liftA3`][lifta3] | `Applicative m => (a -> b -> c -> d) -> m a -> m b -> m c -> m d` | `crocks/helpers/liftA3` |
| [`liftN`][liftn] | `Applicative m => Number -> ((*) -> a) -> (*m) -> m a` | `crocks/helpers/liftN` |
Expand All @@ -90,7 +91,7 @@ need to account for for the rest of your flow.
| [`pipeP`][pipep] | `Promise p => ((a -> p b d), ..., (y -> p z d)) -> a -> p z d` | `crocks/helpers/pipeP` |
| [`pipeS`][pipes] | `Semigroupoid s => (s a b, ..., s y z) -> s a z` | `crocks/helpers/pipeS` |
| [`prop`][prop] | <code>(String &#124; Integer) -> a -> Maybe b</code> | `crocks/Maybe/prop` |
| [`propOr`][propor] | <code>a -> (String &#124; Integer) -> b -> c</code> | `crocks/helpers/propOr` |
| [`propOr`][getpropor]<br /><i>(deprecated)</i> | <code>a -> (String &#124; Integer) -> b -> c</code> | `crocks/helpers/propOr` |
| [`propPath`][proppath] | <code>Foldable f => f (String &#124; Integer) -> a -> Maybe b</code> | `crocks/Maybe/propPath` |
| [`propPathOr`][proppathor] | <code>Foldable f => a -> f (String &#124; Integer) -> b -> c</code> | `crocks/helpers/propPathOr` |
| [`safe`][safe] | <code>((a -> Boolean) &#124; Pred) -> a -> Maybe a</code> | `crocks/Maybe/safe` |
Expand Down Expand Up @@ -149,6 +150,7 @@ type: `Pred a` and vice-versa
[fanout]: helpers.html#fanout
[find]: ../crocks/Maybe.html#find
[frompairs]: helpers.html#frompairs
[getpropor]: helpers.html#getpropor
[lifta2]: helpers.html#lifta2
[lifta3]: helpers.html#lifta3
[liftn]: helpers.html#liftn
Expand All @@ -169,7 +171,6 @@ type: `Pred a` and vice-versa
[pipep]: helpers.html#pipep
[pipes]: helpers.html#pipes
[prop]: ../crocks/Maybe.html#prop
[propor]: helpers.html#propor
[proppath]: ../crocks/Maybe.html#proppath
[proppathor]: helpers.html#proppathor
[safe]: ../crocks/Maybe.html#safe
Expand Down
38 changes: 38 additions & 0 deletions src/helpers/getPropOr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/** @license ISC License (c) copyright 2019 original and current authors */
/** @author Ian Hofmann-Hicks */

const curry = require('../core/curry')
const isDefined = require('../core/isDefined')
const isEmpty = require('../core/isEmpty')
const isNil = require('../core/isNil')
const isInteger = require('../core/isInteger')
const isString = require('../core/isString')

function fn(name) {
function getPropOr(def, key, target) {
if(!(isString(key) && !isEmpty(key) || isInteger(key))) {
throw new TypeError(`${name}: Non-empty String or Integer required for second argument`)
}

if(isNil(target)) {
return def
}

const value = target[key]

return isDefined(value)
? value
: def
}

return curry(getPropOr)
}

// getPropOr : a -> (String | Integer) -> b -> c
const getPropOr =
fn('getPropOr')

getPropOr.origFn =
fn

module.exports = getPropOr

0 comments on commit 6b1b61c

Please sign in to comment.