Created
July 17, 2020 13:53
-
-
Save mishelashala/ef10ae832f1b71c61ac7395cff4a730f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { compose, curry } = require('lodash/fp') | |
// Success :: a -> Success a | |
const Success = value => ({ | |
type: 'success', | |
value | |
}) | |
Success.is = obj => obj.type === 'success' | |
// Failure :: a -> Failure a | |
const Failure = value => ({ | |
type: 'failure', | |
value | |
}) | |
Failure.is = (obj) => obj.type === 'failure' | |
// validateUserName :: User -> Success User | Failure | |
const validateUserName = user => { | |
return !user.name | |
? Failure("Name is required") | |
: Success(user) | |
} | |
// validateUserAge :: User -> Success User | Failure | |
const validateAge = user => { | |
return user.age < 18 | |
? Failure("User is underage") | |
: Success(user) | |
} | |
// bind :: (Success a -> Success a | Failure ) -> Success a -> Succes a | Failure | |
const bind = curry((fn, data) => { | |
if (Success.is(data)) { | |
return fn(data.value) | |
} | |
if (Failure.is(data)) { | |
return data | |
} | |
}); | |
const john = { | |
name: "john doe", | |
age: 18 | |
} | |
// incrementAge :: User -> User | |
const incrementAge = user => { | |
return { | |
...user, | |
age: user.age + 1 | |
} | |
} | |
// map :: (a -> b) -> a -> Success a | Failure | |
const map = curry((fn, data) => { | |
if (Success.is(data)) { | |
return Success(fn(data.value)) | |
} | |
if (Failure.is(data)) { | |
return data | |
} | |
}) | |
// tee :: (a -> b) -> a -> a | |
const tee = curry((fn, data) => { | |
fn(data) | |
return data | |
}) | |
// log :: a -> () | |
const log = msg => { | |
console.log(msg) | |
} | |
// canDrinkAlcohol :: User -> User | |
const canDrinkAlcohol = user => { | |
if (user.age < 21) { | |
throw new Error("Cannot drink, is underage") | |
} | |
return user | |
} | |
// tryCatch :: (a -> b) -> Success a -> Success b | Failure | |
const tryCatch = curry((fn, data) => { | |
try { | |
return Success(fn(data.value)) | |
} catch(err) { | |
return Failure(err.message) | |
} | |
}) | |
// fold :: (a -> ()) -> (b -> ()) -> Success a | Failure -> () | |
const fold = curry((success, failure, data) => { | |
if (Failure.is(data)) { | |
failure(data.value) | |
} | |
if (Success.is(data)) { | |
success(data.value) | |
} | |
}) | |
const notifySuccess = data => { | |
console.log("success: ", data, " yay!") | |
} | |
const notifyFailure = msg => { | |
console.log("failure:", data, " nay!") | |
} | |
// validateUser :: User -> Success User | Failure string | |
const validateUser = compose( | |
fold(notifySuccess, notifyFailure), | |
tryCatch(canDrinkAlcohol), | |
map(incrementAge), | |
map(incrementAge), | |
map(incrementAge), | |
bind(validateAge), | |
validateUserName | |
) | |
validateUser(john) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment