Skip to content

Commit

Permalink
add @@type to ADTs
Browse files Browse the repository at this point in the history
  • Loading branch information
Ian Hofmann-Hicks committed Jan 27, 2018
1 parent c0b3843 commit b25dce0
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 8 deletions.
9 changes: 9 additions & 0 deletions src/All/All.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ test('All', t => {

t.ok(isFunction(All.empty), 'provides an empty function')
t.ok(isFunction(All.type), 'provides a type function')
t.ok(isFunction(All['@@type']), 'provides a @@type function')

const err = /All: Non-function value required/
t.throws(All, err, 'throws with nothing')
Expand Down Expand Up @@ -84,6 +85,14 @@ test('All type', t => {
t.end()
})

test('All @@type', t => {
t.ok(isFunction(All(0)['@@type']), 'is a function')
t.equal(All['@@type'], All(0)['@@type'], 'is the same function as the static type')
t.equal(All(0)['@@type'](), 'crocks/All@0', 'reports crocks/All@0')

t.end()
})

test('All concat functionality', t => {
const a = All(true)
const b = All(false)
Expand Down
10 changes: 5 additions & 5 deletions src/All/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
const _implements = require('../core/implements')
const _inspect = require('../core/inspect')
const type = require('../core/types').type('All')
const _type = require('../core/types').typeFn(type())

const isFunction = require('../core/isFunction')
const isNil = require('../core/isNil')
Expand Down Expand Up @@ -39,6 +40,7 @@ function All(b) {
return {
inspect, toString: inspect,
valueOf, type, concat, empty,
'@@type': _type,
constructor: All
}
}
Expand All @@ -47,10 +49,8 @@ All['@@implements'] = _implements(
[ 'concat', 'empty' ]
)

All.empty =
_empty

All.type =
type
All.empty = _empty
All.type = type
All['@@type'] = _type

module.exports = All
9 changes: 9 additions & 0 deletions src/Any/Any.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ test('Any', t => {

t.ok(isFunction(Any.empty), 'provides an empty function')
t.ok(isFunction(Any.type), 'provides a type function')
t.ok(isFunction(Any['@@type']), 'provides a @@type function')

const err = /Any: Non-function value required/
t.throws(Any, err, 'throws with nothing')
Expand Down Expand Up @@ -85,6 +86,14 @@ test('Any type', t => {
t.end()
})

test('Any @@type', t => {
t.ok(isFunction(Any(0)['@@type']), 'is a function')
t.equal(Any['@@type'], Any(0)['@@type'], 'is the same function as the static type')
t.equal(Any(0)['@@type'](), 'crocks/Any@0', 'reports crocks/Any@0')

t.end()
})

test('Any concat properties (Semigroup)', t => {
const a = Any(0)
const b = Any(true)
Expand Down
3 changes: 3 additions & 0 deletions src/Any/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
const _implements = require('../core/implements')
const _inspect = require('../core/inspect')
const type = require('../core/types').type('Any')
const _type = require('../core/types').typeFn(type())

const isFunction = require('../core/isFunction')
const isNil = require('../core/isNil')
Expand Down Expand Up @@ -39,6 +40,7 @@ function Any(b) {
return {
inspect, toString: inspect,
valueOf, type, concat, empty,
'@@type': _type,
constructor: Any
}
}
Expand All @@ -49,5 +51,6 @@ Any['@@implements'] = _implements(

Any.empty = _empty
Any.type = type
Any['@@type'] = _type

module.exports = Any
14 changes: 13 additions & 1 deletion src/Arrow/Arrow.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ test('Arrow', t => {

t.ok(isFunction(Arrow), 'is a function')

t.ok(isFunction(Arrow.type), 'provides a type function')
t.ok(isFunction(Arrow.id), 'provides an id function')
t.ok(isFunction(Arrow.type), 'provides a type function')
t.ok(isFunction(Arrow['@@type']), 'provides a @@type function')

t.ok(isObject(Arrow(unit)), 'returns an object')

Expand Down Expand Up @@ -80,6 +81,17 @@ test('Arrow type', t => {
t.end()
})

test('Arrow @@type', t => {
const a = Arrow(unit)

t.ok(isFunction(a['@@type']), 'is a function')

t.equal(a['@@type'], Arrow['@@type'], 'static and instance versions are the same')
t.equal(a['@@type'](), 'crocks/Arrow@0', 'reports crocks/Arrow@0')

t.end()
})

test('Arrow runWith', t => {
const f = sinon.spy(identity)
const a = Arrow(f)
Expand Down
3 changes: 3 additions & 0 deletions src/Arrow/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
const _implements = require('../core/implements')
const _inspect = require('../core/inspect')
const type = require('../core/types').type('Arrow')
const _type = require('../core/types').typeFn(type())

const isFunction = require('../core/isFunction')
const isSameType = require('../core/isSameType')
Expand Down Expand Up @@ -88,12 +89,14 @@ function Arrow(runWith) {
inspect, toString: inspect, type,
runWith, id, compose, map, contramap,
promap, first, second, both,
'@@type': _type,
constructor: Arrow
}
}

Arrow.id = _id
Arrow.type = type
Arrow['@@type'] = _type

Arrow['@@implements'] = _implements(
[ 'compose', 'contramap', 'id', 'map', 'promap' ]
Expand Down
7 changes: 6 additions & 1 deletion src/core/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ const type =
const proxy =
t => ({ type: type(t) })

const typeFn = (t, ver) => {
const typeStr = type(t)()
return () => `crocks/${typeStr}@${ver || 0}`
}

module.exports = {
proxy, type
proxy, type, typeFn
}
46 changes: 45 additions & 1 deletion src/core/types.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ const isFunction = require('./isFunction')
const _types = require('./types')

test('types core', t => {
const { proxy, type } = _types
const { proxy, type, typeFn } = _types

t.ok(isFunction(type), 'provides a `types` function')
t.ok(isFunction(proxy), 'provides a `proxy` function')
t.ok(isFunction(typeFn), 'provides a `typeFn` function')

t.end()
})
Expand All @@ -28,6 +29,7 @@ test('type function ', t => {
t.equals(fn('Const'), 'Const', 'returns `Const` for key `Const`')
t.equals(fn('Either'), 'Either', 'returns `Either` for key `Either`')
t.equals(fn('Endo'), 'Endo', 'returns `Endo` for key `Endo`')
t.equals(fn('Equiv'), 'Equiv', 'returns `Equiv` for key `Equiv`')
t.equals(fn('First'), 'First', 'returns `First` for key `First`')
t.equals(fn('Identity'), 'Identity', 'returns `Identity` for key `Identity`')
t.equals(fn('IO'), 'IO', 'returns `IO` for key `IO`')
Expand Down Expand Up @@ -65,6 +67,7 @@ test('proxy function ', t => {
t.equals(fn('Const'), 'Const', 'returns `Const` for key `Const`')
t.equals(fn('Either'), 'Either', 'returns `Either` for key `Either`')
t.equals(fn('Endo'), 'Endo', 'returns `Endo` for key `Endo`')
t.equals(fn('Equiv'), 'Equiv', 'returns `Equiv` for key `Equiv`')
t.equals(fn('First'), 'First', 'returns `First` for key `First`')
t.equals(fn('Identity'), 'Identity', 'returns `Identity` for key `Identity`')
t.equals(fn('IO'), 'IO', 'returns `IO` for key `IO`')
Expand All @@ -86,3 +89,44 @@ test('proxy function ', t => {

t.end()
})

test('typeFn function ', t => {
const { typeFn } = _types

const fn =
(x, v) => typeFn(x, v)()

t.equals(fn('All'), 'crocks/All@0', 'returns `crocks/All@0` for key `All` with no version')
t.equals(fn('All', 1), 'crocks/All@1', 'returns `crocks/All@1` for key `All` with a version of 1')

t.equals(fn('silly'), 'crocks/unknown@0', 'returns `crocks/unknown@0` if key is not defined')
t.equals(fn('All'), 'crocks/All@0', 'returns `crocks/All@0` for key `All`')
t.equals(fn('Any'), 'crocks/Any@0', 'returns `crocks/Any@0` for key `Any`')
t.equals(fn('Arrow'), 'crocks/Arrow@0', 'returns `crocks/Arrow@0` for key `Arrow`')
t.equals(fn('Assign'), 'crocks/Assign@0', 'returns `crocks/Assign@0` for key `Assign`')
t.equals(fn('Async'), 'crocks/Async@0', 'returns `crocks/Async@0` for key `Async`')
t.equals(fn('Const'), 'crocks/Const@0', 'returns `crocks/Const@0` for key `Const`')
t.equals(fn('Either'), 'crocks/Either@0', 'returns `crocks/Either@0` for key `Either`')
t.equals(fn('Endo'), 'crocks/Endo@0', 'returns `crocks/Endo@0` for key `Endo`')
t.equals(fn('Equiv'), 'crocks/Equiv@0', 'returns `crocks/Equiv@0` for key `Equiv`')
t.equals(fn('First'), 'crocks/First@0', 'returns `crocks/First@0` for key `First`')
t.equals(fn('Identity'), 'crocks/Identity@0', 'returns `crocks/Identity@0` for key `Identity`')
t.equals(fn('IO'), 'crocks/IO@0', 'returns `crocks/IO@0` for key `IO`')
t.equals(fn('Last'), 'crocks/Last@0', 'returns `crocks/Last@0` for key `Last`')
t.equals(fn('List'), 'crocks/List@0', 'returns `crocks/List@0` for key `List`')
t.equals(fn('Max'), 'crocks/Max@0', 'returns `crocks/Max@0` for key `Max`')
t.equals(fn('Maybe'), 'crocks/Maybe@0', 'returns `crocks/Maybe@0` for key `Maybe`')
t.equals(fn('Min'), 'crocks/Min@0', 'returns `crocks/Min@0` for key `Min`')
t.equals(fn('Pair'), 'crocks/Pair@0', 'returns `crocks/Pair@0` for key `Pair`')
t.equals(fn('Pred'), 'crocks/Pred@0', 'returns `crocks/Pred@0` for key `Pred`')
t.equals(fn('Prod'), 'crocks/Prod@0', 'returns `crocks/Prod@0` for key `Prod`')
t.equals(fn('Reader'), 'crocks/Reader@0', 'returns `crocks/Reader@0` for key `Reader`')
t.equals(fn('Result'), 'crocks/Result@0', 'returns `crocks/Result@0` for key `Result`')
t.equals(fn('Star'), 'crocks/Star@0', 'returns `crocks/Star@0` for key `Star`')
t.equals(fn('State'), 'crocks/State@0', 'returns `crocks/State@0` for key `State`')
t.equals(fn('Sum'), 'crocks/Sum@0', 'returns `crocks/Sum@0` for key `Sum`')
t.equals(fn('Unit'), 'crocks/Unit@0', 'returns `crocks/Unit@0` for key `Unit`')
t.equals(fn('Writer'), 'crocks/Writer@0', 'returns `crocks/Writer@0` for key `Writer`')

t.end()
})

0 comments on commit b25dce0

Please sign in to comment.