Skip to content

Commit a925f46

Browse files
authored
Merge 308e6e0 into 77ffb2b
2 parents 77ffb2b + 308e6e0 commit a925f46

File tree

9 files changed

+80
-5
lines changed

9 files changed

+80
-5
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# MojiScript ![project:experimental](https://img.shields.io/badge/project-experimental-orange.svg) [![build status](https://travis-ci.org/joelnet/MojiScript.svg?branch=master)](https://travis-ci.org/joelnet/MojiScript) [![Coverage Status](https://coveralls.io/repos/github/joelnet/MojiScript/badge.svg?branch=master&v=1)](https://coveralls.io/github/joelnet/MojiScript?branch=master) ![project:experimental](https://img.shields.io/badge/tests-354-green.svg) [![All Contributors](https://img.shields.io/badge/all_contributors-19-orange.svg?style=flat-square)](#contributors)
1+
# MojiScript ![project:experimental](https://img.shields.io/badge/project-experimental-orange.svg) [![build status](https://travis-ci.org/joelnet/MojiScript.svg?branch=master)](https://travis-ci.org/joelnet/MojiScript) [![Coverage Status](https://coveralls.io/repos/github/joelnet/MojiScript/badge.svg?branch=master&v=1)](https://coveralls.io/github/joelnet/MojiScript?branch=master) ![project:experimental](https://img.shields.io/badge/tests-356-green.svg) [![All Contributors](https://img.shields.io/badge/all_contributors-19-orange.svg?style=flat-square)](#contributors)
22

33
![MojiScript logo](https://raw.githubusercontent.com/joelnet/MojiScript/master/media/MS_logo_64.png)
44

type/Either.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,20 @@ const fromEither = def => either => isRight(either) ? either.value : def
1515
// fromNullable :: Any -> Either
1616
const fromNullable = value => value == null ? Left(value) : Right(value)
1717

18+
// try :: Thunk -> Maybe
19+
const maybeTry = thunk => {
20+
try {
21+
return Right(thunk())
22+
} catch (err) {
23+
return Left(err)
24+
}
25+
}
26+
1827
module.exports['@@type'] = typeEither
1928
module.exports.fromFalsy = fromFalsy
2029
module.exports.fromEither = fromEither
2130
module.exports.fromNullable = fromNullable
31+
module.exports.try = maybeTry
2232

2333
// Experimental debug code
2434
/* istanbul ignore next */

type/Left.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const is = require('./is')
22
const { typeLeft } = require('./_allTypes')
33

4+
const isError = is(Error)
45
const isFunction = is(Function)
56

67
// Left :: Any -> Left
@@ -47,7 +48,13 @@ const prototype = {
4748
leftFlatMap,
4849
'fantasy-land/ap': ap,
4950
'fantasy-land/map': map,
50-
inspect() { return `Left (${isFunction(this.value) ? `function ${this.value.name}()` : JSON.stringify(this.value)})` }
51+
inspect() {
52+
const value =
53+
isFunction(this.value) ? `function ${this.value.name}()`
54+
: isError(this.value) ? `[ Error: ${this.value.message} ]`
55+
: JSON.stringify(this.value)
56+
return `Left (${value})`
57+
}
5158
}
5259

5360
Left['@@type'] = typeLeft

type/Maybe.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@ const fromMaybe = def => maybe => isJust(maybe) ? maybe.value : def
1515
// fromNullable :: Any -> Maybe
1616
const fromNullable = value => value == null ? Nothing : Just(value)
1717

18+
// unlift :: Function -> Array -> Any
19+
const unlift = func => (...args) =>
20+
func(...args.map(fromNullable)).value
21+
1822
module.exports['@@type'] = typeMaybe
1923
module.exports.fromFalsy = fromFalsy
2024
module.exports.fromMaybe = fromMaybe
2125
module.exports.fromNullable = fromNullable
26+
module.exports.unlift = unlift
2227

2328
// Experimental debug code
2429
/* istanbul ignore next */

type/Right.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const is = require('./is')
22
const { typeRight } = require('./_allTypes')
33

4+
const isError = is(Error)
45
const isFunction = is(Function)
56

67
// Right :: Any -> Right
@@ -47,7 +48,14 @@ const prototype = {
4748
leftFlatMap,
4849
'fantasy-land/ap': ap,
4950
'fantasy-land/map': map,
50-
inspect() { return `Right (${isFunction(this.value) ? `function ${this.value.name}()` : JSON.stringify(this.value)})` }
51+
inspect() {
52+
const value =
53+
isFunction(this.value) ? `function ${this.value.name}()`
54+
: isError(this.value) ? `[ Error: ${this.value.message} ]`
55+
: JSON.stringify(this.value)
56+
57+
return `Right (${value})`
58+
}
5159
}
5260

5361
Right['@@type'] = typeRight

type/__tests__/Either.test.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
const is = require('../is')
22
const Right = require('../Right')
33
const Left = require('../Left')
4-
const { fromFalsy, fromNullable, fromEither } = require('../Either')
4+
const Either = require('../Either')
5+
const { fromFalsy, fromNullable, fromEither } = Either
56

67
describe('Either', () => {
78
describe('fromFalsy', () => {
@@ -121,4 +122,18 @@ describe('Either', () => {
121122
expect(actual).toBe(expected)
122123
})
123124
})
125+
126+
describe('try', () => {
127+
test('success returns Right', () => {
128+
const expected = Right(123)
129+
const actual = Either.try(() => 123)
130+
expect(actual).toMatchObject(expected)
131+
})
132+
133+
test('error returns Left', () => {
134+
const expected = Left(Error('UH OH'))
135+
const actual = Either.try(() => { throw Error('UH OH')})
136+
expect(actual).toMatchObject(expected)
137+
})
138+
})
124139
})

type/__tests__/Left.test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,13 @@ describe('type/Left', () => {
105105
expect(actual).toEqual(expected)
106106
})
107107

108+
test('Left(Error).inspect', () => {
109+
expect.assertions(1)
110+
const expected = 'Left ([ Error: UH OH ])'
111+
const actual = Left(Error('UH OH')).inspect()
112+
expect(actual).toEqual(expected)
113+
})
114+
108115
test('Left(add()).inspect', () => {
109116
expect.assertions(1)
110117
const add = () => {}

type/__tests__/Maybe.test.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
const is = require('../is')
22
const Just = require('../Just')
3-
const { fromFalsy, fromNullable, fromMaybe } = require('../Maybe')
3+
const { fromFalsy, fromNullable, fromMaybe, unlift } = require('../Maybe')
44
const Nothing = require('../Nothing')
55

6+
const toStringMaybe = maybe => maybe.map(value => value.toUpperCase())
7+
68
describe('Maybe', () => {
79
describe('fromFalsy', () => {
810
test('null is Nothing', () => {
@@ -121,4 +123,18 @@ describe('Maybe', () => {
121123
expect(actual).toBe(expected)
122124
})
123125
})
126+
127+
describe('unlift', () => {
128+
test('Just', () => {
129+
const expected = "ABC"
130+
const actual = unlift(toStringMaybe)("abc")
131+
expect(actual).toBe(expected)
132+
})
133+
134+
test('Nothing', () => {
135+
const expected = null
136+
const actual = unlift(toStringMaybe)(null)
137+
expect(actual).toBe(expected)
138+
})
139+
})
124140
})

type/__tests__/Right.test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ describe('type/Right', () => {
8484
expect(actual).toEqual(expected)
8585
})
8686

87+
test('Right(function()).inspect', () => {
88+
expect.assertions(1)
89+
const expected = 'Right ([ Error: UH OH ])'
90+
const actual = Right(Error('UH OH')).inspect()
91+
expect(actual).toEqual(expected)
92+
})
93+
8794
test('Right(add()).inspect', () => {
8895
expect.assertions(1)
8996
const add = () => {}

0 commit comments

Comments
 (0)