Why would validation break the monad laws?
Asked Answered
B

1

6

On SO an explanation is given why a Validation like in scalaz, cats (Scala), or Arrow (Kotlin) can't be a monad.

As far as I understand it's because they've modelled monads in terms of applicative functors and the desired behaviour of a Validation as applicative (gathering all invalids) is different from the desired behaviour of a Validation as monad (sequence validations and fail fast on the first invalid). As a result you need to convert a validation into an either (which is a monad) when you want the fail fast.

On https://groups.google.com/forum/#!msg/scalaz/IWuHC0nlVws/syRUkXJklWIJ, they mention the reason validation is not a monad, is because the following property would not hold:

x <|*|> y === x >>= (a => y map ((a, _))) 

But looking at the definition of a monad, the property above is not part of the monad laws. So, is this a result of the fact that monads are implemented in terms of applicatives, or is the above property a prerequisite for being a monad?

This higher kind reasoning is all quit new to me, but in my limited understanding of FP, I could have a validation data type that has one kind of behaviour when used as an applicative (accumulating invalids) and another behaviour when used as a monad (failing fast).

Baskerville answered 4/5, 2018 at 11:54 Comment(1)
Possible duplicate of Why can AccValidation not have a Monad instance?Thane
B
6

You've got all the pieces right. Yes, a lawful monad instance for Validation is possible. The problem is that it would yield two different Applicative instances for Validation: one accumulating the errors, the other one derived from the monad instance and failing fast. This would lead to typeclass incoherence: the program behavior depending on how the typeclass instance was arrived at.

The property you mention,

x <|*|> y === x >>= (a => y map ((a, _)))

can serve as the definition of <|*|> in terms of >>= and map, and thus holds automatically for an Applicative derived from a Monad. The problem is that there's already a different Applicative with a different behavior of <|*|>.

Billow answered 4/5, 2018 at 12:54 Comment(9)
a lawful monad instance for Validation is not possible... You can have a look here : #40540150Thane
and here : #50844542Thane
you cannot have monadic sequence of actions on a part a of the functor structure, only on the value part of the functor...Thane
The monad instance I'm talking about would behave the same as the monad for Either. It is lawful. There are 3 monad laws (left identity, right identity, associativity), all of which are satisfied.Billow
Then it's the Either Monad disguised, not the one (that doesn't exist) from the Validation Applicative.. You can have multiple Applicatives for the same Functor (e.g Either functor has the either applicative and the validation applicative, Validation is just a rename of Either to make the distinction between the 2). There are as much applicatives as you can have Monoids to squash 2 functors structure together. But you have only one monad for one applicativeThane
Yes. I think I made it clear in my answer that this monad gives rise to a different Applicative than the one we are usually interested in.Billow
ho... since Validation without his Applicative has no utility compared to Either... I have been confused by how you've explained it.... It's the title of the library in haskell : "Validation: A data-type like Either but with an accumulating Applicative", Validation exists only because of its Applicative...Thane
I attempted to clarify specifically that which seemed to be confusing to the author of the question. It is possible that someone coming with a different set of assumptions (like "Validation is inseparable from its Applicative") will find my answer more confusing than clarifying.Billow
Btw, regarding "you have only one monad for one applicative", this answer has a counter-example at the end.Billow

© 2022 - 2024 — McMap. All rights reserved.