Skip to content

Commit

Permalink
have tryCatch return a Result instead of an Either
Browse files Browse the repository at this point in the history
  • Loading branch information
Ian Hofmann-Hicks committed Mar 22, 2017
1 parent 8669137 commit b914696
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 15 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,9 @@ It is hard knowing what is going on inside of some of these ADTs or your wonderf

#### tryCatch
```haskell
tryCatch : (a -> b) -> a -> Either e b
tryCatch : (a -> b) -> a -> Result e b
```
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 an `Either.Right` if everything was good, or an error wrapped in an `Either.Left` if it fails.
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.

### Logic Functions
The functions in this section are used to represent logical branching in a declarative manner. Each of these functions require either `Pred`s or predicate functions in their input. Since these functions work with `Pred`s and predicate functions, rather than values, this allows for composeable, "lazy" evaluation.
Expand Down Expand Up @@ -328,13 +328,13 @@ Say you have two predicate functions or `Pred`s and would like to combine them i

#### unless
```haskell
unless : ((a -> Boolean) | Pred) -> (* -> a) -> * -> a
unless : ((a -> Boolean) | Pred) -> (a -> a) -> a -> a
```
There may come a time when you need to adjust a value when a condition is false, that is where `unless` can come into play. Just provide a predicate function (a function that returns a Boolean) and a function to apply your desired modification. This will get you back a function that when you pass it a value, it will evaluate it and if false, will run your value through the provided function. Either the original or modified value will be returned depending on the result of the predicate. Check out [`when`](#when) for a negated version of this function.

#### when
```haskell
when : ((a -> Boolean) | Pred) -> (* -> a) -> * -> a
when : ((a -> Boolean) | Pred) -> (a -> a) -> a -> a
```
There may come a time when you need to adjust a value when a condition is true, that is where `when` can come into play. Just provide a predicate function (a function that returns a Boolean) and a function to apply your desired modification. This will get you back a function that when you pass it a value, it will evaluate it and if true, will run your value through the provided function. Either the original or modified value will be returned depending on the result of the predicate. Check out [`unless`](#unless) for a negated version of this function.

Expand Down
10 changes: 5 additions & 5 deletions helpers/tryCatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ const isFunction = require('../predicates/isFunction')

const curry = require('./curry')

const Either = require('../crocks/Either')
const Result = require('../crocks/Result')

const Left = Either.Left
const Right = Either.Right
const Err = Result.Err
const Ok = Result.Ok

function tryCatch(fn) {
if(!isFunction(fn)) {
throw new TypeError('tryCatch: Function required for first argument')
}
return function(x) {
try { return Right(fn(x)) }
catch(e) { return Left(e) }
try { return Ok(fn(x)) }
catch(e) { return Err(e) }
}
}

Expand Down
24 changes: 18 additions & 6 deletions helpers/tryCatch.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ const bindFunc = helpers.bindFunc
const noop = helpers.noop

const isFunction = require('../predicates/isFunction')
const isSameType = require('../predicates/isSameType')

const either = require('../pointfree/either')

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

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

const tryCatch = require('./tryCatch')

Expand All @@ -34,17 +38,25 @@ test('tryCatch', t => {
})

test('tryCatch functionality', t => {
const msg = 'silly error'

const f = x => x
const g = () => { throw new Error('silly error') }
const g = () => { throw new Error(msg) }

const extract =
either(constant('left'), constant('right'))
either(identity, constant('Ok'))

const ok = tryCatch(f, null)
const err = tryCatch(g, null)

t.ok(isSameType(Result, ok), 'Non-error returns a Result')
t.ok(isSameType(Result, err), 'Error returns a Result')

const right = extract(tryCatch(f, null))
const left = extract(tryCatch(g, null))
const good = extract(ok)
const bad = extract(err)

t.equals(right, 'right', 'returns a Right when no error')
t.equals(left, 'left', 'returns a Left when error')
t.equals(good, 'Ok', 'returns an Ok when no error')
t.equals(bad.message, msg, 'returns an Err with error on error')

t.end()
})

0 comments on commit b914696

Please sign in to comment.