Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the Last Monoid #130

Merged
merged 2 commits into from
Jul 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ All `Monoids` provide `empty` and `type` function on their Constructors as well
| `Any` | Boolean | Logical OR | `false` |
| `Assign` | Object | `Object.assign` | `{}` |
| `Endo` | Function | `compose` | `identity` |
| `Last` | Maybe | Last `Just` | `Nothing` |
| `Max` | Number | `Math.max` | `-Infinity` |
| `Min` | Number | `Math.min` | `Infinity` |
| `Prod` | Number | Multiplication | `1` |
Expand Down Expand Up @@ -860,12 +861,19 @@ bad
|---|---|---|
| `arrayToList` | `[ a ] -> List a` | `(a -> [ b ]) -> a -> List b` |
| `eitherToAsync` | `Either e a -> Async e a` | `(a -> Either e b) -> a -> Async e b` |
| `eitherToLast` | `Either b a -> Last a` | `(a -> Either c b) -> a -> Last b` |
| `eitherToMaybe` | `Either b a -> Maybe a` | `(a -> Either c b) -> a -> Maybe b` |
| `eitherToResult` | `Either e a -> Result e a` | `(a -> Either e b) -> a -> Result e b` |
| `lastToAsync` | `e -> Last a -> Async e a` | `e -> (a -> Last b) -> a -> Last e b` |
| `lastToEither` | `c -> Last a -> Either c a` | `c -> (a -> Last b) -> a -> Either c b` |
| `lastToMaybe` | `Last a -> Maybe a` | `(a -> Last b) -> a -> Maybe b` |
| `lastToResult` | `c -> Last a -> Result c a` | `c -> (a -> Last b) -> a -> Result c b` |
| `listToArray` | `List a -> [ a ]` | `(a -> List b) -> a -> [ b ]` |
| `maybeToAsync` | `e -> Maybe a -> Async e a` | `e -> (a -> Maybe b) -> a -> Async e b` |
| `maybeToEither` | `c -> Maybe a -> Either c a` | `c -> (a -> Maybe b) -> a -> Either c b` |
| `maybeToLast` | `Maybe a -> Last a` | `(a -> Maybe b) -> a -> Last b` |
| `maybeToResult` | `c -> Maybe a -> Result c a` | `c -> (a -> Maybe b) -> a -> Result c b` |
| `resultToAsync` | `Result e a -> Async e a` | `(a -> Result e b) -> a -> Async e b` |
| `resultToEither` | `Result e a -> Either e a` | `(a -> Result e b) -> a -> Either e b` |
| `resultToMaybe` | `Result b a -> Maybe a` | `(a -> Result c b) -> a -> Maybe b` |
| `resultToLast` | `Result e a -> Last a` | `(a -> Result e b) -> a -> Last b` |
| `resultToMaybe` | `Result e a -> Maybe a` | `(a -> Result e b) -> a -> Maybe b` |
8 changes: 8 additions & 0 deletions crocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ const monoids = {
Any: require('./monoids/Any'),
Assign: require('./monoids/Assign'),
Endo: require('./monoids/Endo'),
Last: require('./monoids/Last'),
Min: require('./monoids/Min'),
Max: require('./monoids/Max'),
Prod: require('./monoids/Prod'),
Expand Down Expand Up @@ -168,14 +169,21 @@ const predicates = {
const transforms = {
arrayToList: require('./transforms/arrayToList'),
eitherToAsync: require('./transforms/eitherToAsync'),
eitherToLast: require('./transforms/eitherToLast'),
eitherToMaybe: require('./transforms/eitherToMaybe'),
eitherToResult: require('./transforms/eitherToResult'),
lastToAsync: require('./transforms/lastToAsync'),
lastToEither: require('./transforms/lastToEither'),
lastToMaybe: require('./transforms/lastToMaybe'),
lastToResult: require('./transforms/lastToResult'),
listToArray: require('./transforms/listToArray'),
maybeToAsync: require('./transforms/maybeToAsync'),
maybeToEither: require('./transforms/maybeToEither'),
maybeToLast: require('./transforms/maybeToLast'),
maybeToResult: require('./transforms/maybeToResult'),
resultToAsync: require('./transforms/resultToAsync'),
resultToEither: require('./transforms/resultToEither'),
resultToLast: require('./transforms/resultToLast'),
resultToMaybe: require('./transforms/resultToMaybe')
}

Expand Down
16 changes: 16 additions & 0 deletions crocks.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ const All = require('./monoids/All')
const Any = require('./monoids/Any')
const Assign = require('./monoids/Assign')
const Endo = require('./monoids/Endo')
const Last = require('./monoids/Last')
const Min = require('./monoids/Min')
const Max = require('./monoids/Max')
const Prod = require('./monoids/Prod')
Expand Down Expand Up @@ -155,14 +156,21 @@ const isTraversable = require('./predicates/isTraversable')

const arrayToList = require('./transforms/arrayToList')
const eitherToAsync = require('./transforms/eitherToAsync')
const eitherToLast = require('./transforms/eitherToLast')
const eitherToMaybe = require('./transforms/eitherToMaybe')
const eitherToResult = require('./transforms/eitherToResult')
const lastToAsync = require('./transforms/lastToAsync')
const lastToEither = require('./transforms/lastToEither')
const lastToMaybe = require('./transforms/lastToMaybe')
const lastToResult = require('./transforms/lastToResult')
const listToArray = require('./transforms/listToArray')
const maybeToAsync = require('./transforms/maybeToAsync')
const maybeToEither = require('./transforms/maybeToEither')
const maybeToLast = require('./transforms/maybeToLast')
const maybeToResult = require('./transforms/maybeToResult')
const resultToAsync = require('./transforms/resultToAsync')
const resultToEither = require('./transforms/resultToEither')
const resultToLast = require('./transforms/resultToLast')
const resultToMaybe = require('./transforms/resultToMaybe')

test('entry', t => {
Expand Down Expand Up @@ -274,6 +282,7 @@ test('entry', t => {
t.equal(crocks.Any, Any, 'provides the Any monoid')
t.equal(crocks.Assign, Assign, 'provides the Assign monoid')
t.equal(crocks.Endo, Endo, 'provides the Endo monoid')
t.equal(crocks.Last, Last, 'provides the Last monoid')
t.equal(crocks.Min, Min, 'provides the Min monoid')
t.equal(crocks.Max, Max, 'provides the Max monoid')
t.equal(crocks.Prod, Prod, 'provides the Prod monoid')
Expand Down Expand Up @@ -322,13 +331,20 @@ test('entry', t => {
t.equal(crocks.arrayToList, arrayToList, 'provides the arrayToList function')
t.equal(crocks.eitherToAsync, eitherToAsync, 'provides the eitherToAsync function')
t.equal(crocks.eitherToMaybe, eitherToMaybe, 'provides the eitherToMaybe function')
t.equal(crocks.eitherToLast, eitherToLast, 'provides the eitherToLast function')
t.equal(crocks.eitherToResult, eitherToResult, 'provides the eitherToResult function')
t.equal(crocks.lastToAsync, lastToAsync, 'provides the lastToAsync function')
t.equal(crocks.lastToEither, lastToEither, 'provides the lastToEither function')
t.equal(crocks.lastToMaybe, lastToMaybe, 'provides the lastToMaybe function')
t.equal(crocks.lastToResult, lastToResult, 'provides the lastToResult function')
t.equal(crocks.listToArray, listToArray, 'provides the listToArray function')
t.equal(crocks.maybeToAsync, maybeToAsync, 'provides the maybeToAsync function')
t.equal(crocks.maybeToEither, maybeToEither, 'provides the maybeToEither function')
t.equal(crocks.maybeToLast, maybeToLast, 'provides the maybeToLast function')
t.equal(crocks.maybeToResult, maybeToResult, 'provides the maybeToResult function')
t.equal(crocks.resultToAsync, resultToAsync, 'provides the resultToAsync function')
t.equal(crocks.resultToEither, resultToEither, 'provides the resultToEither function')
t.equal(crocks.resultToLast, resultToLast, 'provides the resultToLast function')
t.equal(crocks.resultToMaybe, resultToMaybe, 'provides the resultToMaybe function')

t.end()
Expand Down
2 changes: 1 addition & 1 deletion crocks/Const.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ test('Const equals properties (Setoid)', t => {
t.end()
})

test('Const concat properties (Semigoup)', t => {
test('Const concat properties (Semigroup)', t => {
const a = Const(0)
const b = Const(true)
const c = Const('')
Expand Down
2 changes: 1 addition & 1 deletion crocks/Either.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ test('Either concat functionality', t => {
t.end()
})

test('Either concat properties (Semigoup)', t => {
test('Either concat properties (Semigroup)', t => {
const extract =
either(identity, identity)

Expand Down
2 changes: 1 addition & 1 deletion crocks/Identity.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ test('Identity concat functionality', t => {
t.end()
})

test('Identity concat properties (Semigoup)', t => {
test('Identity concat properties (Semigroup)', t => {
const extract =
m => m.value()

Expand Down
2 changes: 1 addition & 1 deletion crocks/Maybe.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ test('Maybe concat functionality', t => {
t.end()
})

test('Maybe concat properties (Semigoup)', t => {
test('Maybe concat properties (Semigroup)', t => {
const extract =
either(constant('Nothing'), identity)

Expand Down
2 changes: 1 addition & 1 deletion crocks/Pred.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ test('Pred concat functionality', t => {
t.end()
})

test('Pred concat properties (Semigoup)', t => {
test('Pred concat properties (Semigroup)', t => {
const a = Pred(constant(false))
const b = Pred(constant(true))
const c = Pred(constant(false))
Expand Down
2 changes: 1 addition & 1 deletion crocks/Result.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ test('Result concat functionality', t => {
t.end()
})

test('Result concat properties (Semigoup)', t => {
test('Result concat properties (Semigroup)', t => {
const extract =
either(identity, identity)

Expand Down
2 changes: 1 addition & 1 deletion crocks/Unit.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ test('Unit equals properties (Setoid)', t => {
t.end()
})

test('Unit concat properties (Semigoup)', t => {
test('Unit concat properties (Semigroup)', t => {
const a = Unit(0)
const b = Unit(true)
const c = Unit('')
Expand Down
2 changes: 1 addition & 1 deletion monoids/All.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ test('All concat functionality', t => {
t.end()
})

test('All concat properties (Semigoup)', t => {
test('All concat properties (Semigroup)', t => {
const a = All(0)
const b = All(true)
const c = All('')
Expand Down
2 changes: 1 addition & 1 deletion monoids/Any.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ test('Any type', t => {
t.end()
})

test('Any concat properties (Semigoup)', t => {
test('Any concat properties (Semigroup)', t => {
const a = Any(0)
const b = Any(true)
const c = Any('')
Expand Down
73 changes: 73 additions & 0 deletions monoids/Last.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/** @license ISC License (c) copyright 2017 original and current authors */
/** @author Ian Hofmann-Hicks (evil) */

const _implements = require('../internal/implements')
const _inspect = require('../internal/inspect')

const constant = require('../combinators/constant')
const identity = require('../combinators/identity')
const isSameType = require('../predicates/isSameType')

const Maybe = require('../crocks/Maybe')

const _empty =
() => Last(Maybe.Nothing())

const _type =
constant('Last')

function Last(x) {
if(!arguments.length) {
throw new TypeError('Last: Requires one argument')
}

const maybe =
!isSameType(Maybe, x) ? Maybe.of(x) : x.map(identity)

const value =
constant(maybe)

const type =
_type

const empty =
_empty

const inspect =
constant(`Last(${_inspect(maybe)} )`)

const option =
maybe.option

function concat(m) {
if(!isSameType(Last, m)) {
throw new TypeError('Last.concat: Last required')
}

const n =
m.value().map(identity)

return Last(
maybe.either(
constant(n),
constant(n.either(constant(maybe), constant(n)))
)
)
}

return {
concat, empty, inspect, option, type, value
}
}

Last['@@implements'] = _implements(
[ 'concat', 'empty' ]
)

Last.empty =
_empty

Last.type =
_type

module.exports = Last
Loading