origamitower / folktale

[not actively maintained!] A standard library for functional programming in JavaScript
https://folktale.origamitower.com/
MIT License
2.04k stars 102 forks source link

Result.Ok filter function throws away the value when predicate returns false #209

Closed joseaquino closed 5 years ago

joseaquino commented 5 years ago

When using filter on a Result data structure the value gets thrown away if the predicate fails, so when using mapError the value is no longer accesible therefore the value given to the function in mapError always receives undefined.

Steps to reproduce

import Result from 'folktale/result'
import isObject from 'crocks/predicates/isObject'
import { compose, prop, replace, type } from 'ramda'

// throwError :: String -> _
const throwError = err => { 
    throw new TypeError(err)
}

// invalidObjectError :: a -> String
const invalidObjectError = data => 
`The function {funcName} expected an Object but got ${type(data)}`

// assertIsObject :: a -> Result String Object
const assertIsObject = value => 
    Result.of(value)
        .filter(isObject)
        .mapError(invalidObjectError)

// someFunction :: Object -> Object
const someFunction = obj =>
    assertIsObject(obj)
         .matchWith({
             Ok: ({ value }) => value,
             Error: compose(
                 throwError,
                 replace('{funcName}', 'someFunction'),
                 prop('value')
              )
         })

someFunction('shouldThrowError')

Expected behaviour

For a type error to be thrown with the message:

TypeError
The function someFunction expected an Object but got String

Observed behaviour

The type error is thrown but the type of the value passed to mapError is undefined because filter throws away the value if the predicate fails, while mapError does expect for the Result.Error to have a value, which gets passed to the function given to mapError.

Should filter return Error(this.value) instead of just Error() when the predicate fails?

robotlolita commented 5 years ago

This should be fixed in 2.3.1, can you test and let me know if it works for you?

joseaquino commented 5 years ago

Thank you @robotlolita! It works as expected