Closed diegovdc closed 6 years ago
Curious if you can give an example of needing to do this.
There is nothing in crocks
that does this for a few reasons.
But you can make a set of functions if you need to do this like so:
const { constant, either } = require('crocks')
// isRight :: Either a b -> Boolean
const isRight =
either(constant(false), constant(true))
// isLeft :: Either a b -> Boolean
const isLeft =
either(constant(true), constant(false))
Though if you could post an example of how you would use these functions, I may be able to show you how to not need them, and just rely on the Disjunction that is encoded in the Either
type.
EDIT:
There really is no reason to build it for each case, as isRight
is a predicate function, you can use not
for isLeft
:
const { constant, either, not } = require('crocks')
// isRight :: Either a b -> Boolean
const isRight =
either(constant(false), constant(true))
// isLeft :: Either a b -> Boolean
const isLeft =
not(isRight)
So you will notice that all these functions do is map to Boolean
, false for Left
, true for Right
. And work with the negation for isLeft
....That is because this disjunction is what Either
encodes.
So if you need to do something based on its instance you can use bimap
:
const { bimap } = require('crocks')
// Either is a Bifunctor
// fn :: Bifunctor f => f -> f
const fn =
bimap(doSomethingIfLeft, doSomethingIfRight)
here we represent the disjunction in the type and process the value bases on the instance.
Thanks @evilsoft
I am using Either
to validate, the user's input. As part of the codebase if built with Folktale's data.task
, I want to to transform my Either
s into a Task
, so if there is any Left
in the object, it goes to Task.rejected
with the contents of the Left
s folded. Else it goes to Task.of
also folded.
const validateCreateUser = R.pipe(
R.applySpec({
fname: body => isNilOrEmpty(body.fname)
? Left('El nombre es requerido')
: Right(body.fname),
lname: body => isNilOrEmpty(body.lname)
? Left('El apellido es requerido')
: Right(body.lname),
email: body =>
isNilOrEmpty(body.email) ? Left('El email es requerido') :
!isValidEmail(body.email) ? Left('El email es no es un correo válido')
: Right(body.email),
password: body =>
isNilOrEmpty(body.password) ? Left('El password es requerido') :
body.password.length < 6 ? Left('El password debe ser de al menos 6 caracteres')
: Right(body.password),
password_confirmation: body => body.password !== body.password_confirmation
? Left('El password y su confirmación no coinciden') :
Right(body.password_confirmation),
}),
fromValidatedEitherToTask
)
At the moment I switched to data.either
, so fromValidatedEitherToTask
. But I guess there must be a better way. But I wanted to start using crocks
to get to know the library better.
const fromValidatedEitherToTask = objOfEithers => R.pipe(
R.partition(either => either.isLeft),
([left, right]) => R.isEmpty(left)
? Task.of(R.map(r => r.fold(R.identity, R.identity), right))
: Task.rejected(R.map(l => l.fold(R.identity, R.identity), left)),
)(objOfEithers)
Ah. I see, yep you are forced into that with partition.
You could move back to crocks Either
and use T
and F
from ramda.
then while it is the same flow, you could do something like:
const { bimap, either } = require('crocks')
const isLeft =
either(R.T, R.F)
const rejectFirst = R.ifElse(
R.compose(R.isEmpty, R.head),
R.compose(Task.of, R.nth(1)),
R.compose(Task.rejected, R.head)
)
const extract =
R.map(either(R.identity, R.identity))
const fromValidatedEitherToTask = R.pipe(
R.partition(isLeft),
rejectFirst,
bimap(extract, extract)
)
You will be in the same boat as before, so this really adds nothing.
Thanks for taking the time to elaborate on that example. It's very cool!
Hi, I was following the topic and seems that you could go about using tagged predicates as @evilsoft showed in one of the earlier videos (https://www.youtube.com/watch?v=I7yvTw2Yoo0). The solution is very elegant for taking first error message that comes in the list of validations and it is given back as a Maybe which you can chain further to a Task.
Can't find any method in the docs.