In your documentation on Validated under 'Improvin...
# arrow
p
In your documentation on Validated under 'Improving the validation' you have the following example:
Copy code
val parallelValidate = Validated.applicativeNel<ConfigError>()
    .tupledN(v1.toValidatedNel(), v2.toValidatedNel()).fix()
    .map { (a, b) -> /* combine the result */}
This example works, but it works only for values that are not optional?, so the current implementation is rather useless as you will not have Forms with every field mandatory (or Object with only mandatory fields when you create an instance in map {...} after validating each field. Should I consider this as a bug and report it or how would I validate a bunch of fields where some of them can be null?
r
Hi @Pueffl, do you have a code example that you think should work? I don't understand what you mean by values that are not optional.
p
I want to use that code in a Builder to create. The code looks like this (just build() but I hope it is clear what it does):
Copy code
fun build(): Validated<NonEmptyList<Failure>, PwdAuthentication> {

    val valId = nonNull(id, "id").flatMap { Id.create(it, "id") }
    val valOwnerid = nonNull(ownerId, "ownerId").flatMap { Id.create(it, "ownerId") }
    val valUsername = nonNull(username, "username").flatMap { NonBlankString.create(it, "username") }
    val valPassword = nonNull(password, "password").flatMap { Password.create(it, "password") }

    return Validated.applicativeNel<Failure>()
        .tupledN(
            Validated.fromEither(valId).toValidatedNel(),
            Validated.fromEither(valOwnerid).toValidatedNel(),
            Validated.fromEither(valUsername).toValidatedNel(),
            Validated.fromEither(valPassword).toValidatedNel()
        )
        .fix()
        .map { (id, ownerId, username, password) ->
            PwdAuthentication(id, ownerId, username, password)}
}
This works fine but it would not if one of the fields (e.g. ownerId) of PwdAuthentication would be optional? and null for this validation. In that case, I can't use tupleN because there is no validation for ownerId. At the moment I'm trying to figure out how to solve this (all help appreciated :-)). For me, the example in the docs is rather a special case which will work sometimes, but usually you will have values that are just null or not set and then this example is not very helpful. As an ordinary (and rather new) user I search for a pattern that works in any case and this pattern does not, so I wouldn't use it at all (but maybe I just miss something).
I think, this would work fine with Validated<Failure, Option<Value>>, but Option is deprecated and it doesn't work with Validated<Failure, Value?>
j
You can use Either instead of Option on the right side of Validated. I think the type on the left side of the Either would be Unit.
p
Thx. Let me try that :-)
👍 1
j
You can also create a typealias Option that represents the Either, in order to simplify usage.
p
@julian Well, I considered this and I think it would work, but I don't want to introduce some workaround. Actually I'm looking for a solution that just works with 'value?'. But thanks, this may be a good hint for some other problems that may arise on the road...
👍🏾 1
j
If it makes you feel better about it, from what I've read on this channel, creating a typealias Option for Either isn't considered a workaround, but a recommended practice when working with Kotlin nullables isn't possible.
r
Option is being relocated so you can rely on Option for now. It will not dissapear and it will remain available in the next release. Unless we have a bad signature you should be able to combine fine nullable and non-nullable types in the arity of mapN
If you can provide a gist with a reduced example or this one with imports so it compiles or fails to compile where you are trying to make it work we can look at it and see what can be done.
s
Works fine with nullable types here: https://github.com/arrow-kt/frdomain.kt/blob/bca195d7d18c9855a94b13c420678f380232311d/arrow-fx/src/main/kotlin/io/arrowkt/frdomain/model/Account.kt#L31 At least it typechecks... I am not sure if I ever executed it 😅
r
yeah, that the type is nullable should not matter because mapN preserves arity of any type and combines them in the transformation function tupled
That’s why I was asking for a reduced example because I don’t yet understand the issue or if there is one
p
@stojan Thx. I will check that out and come back when I need support. @raulraja Can also provide a gist if necwessary, but just let me try.
👍 2
@stojan I checked your solution: this is a variant of @julian’s suggestion. You don't use nullable types. You use a Pair as a wrapper of nullable types, but this may be the easiest workaround (maybe I try something like that). But I'm looking for a solutions without the wrapper (a really clean solution without some workaround).
j
Pair is a product type, whereas Option is a sum type. 😬 This difference is meaningful.
p
In that specific case it is just used as a wrapper for nullables.
s
If nullable types don't work it might be related to https://github.com/arrow-kt/arrow-core/issues/147 Keep using Option for the time being (it's not gonna get removed, just moved to a separate module) or do the Either with Unit on the left
p
Well, actually might be mores related to https://github.com/arrow-kt/arrow-core/pull/239 🙂 So do I understand you right: Option will no longer be deprecated in 1.0, just moved to another module?
s
That PR is blocked by the issue I linked 😅 Yup, the idea is to move Option to a separate module. Nullable types cover most of it's use cases. Only in rare occasions you would need the Option type.