I am trying to write a small Rule / Validation mechanism that allows you to bind rules using HLists. Now the code below compiles fine, but I cannot use the class Validation, and as a beginner I am stuck here figuring out why.
trait Rule {
type Value
}
object Rule {
type Aux[T] = Rule { type Value = T }
}
abstract class RuleOps[R <: Rule]( rule: R )(
implicit
definition: Definition[R],
show: Show[R]
) {
def validate( value: R#Value ): Result[R#Value] = {
definition( value, rule ) match {
case true ⇒ Success( value )
case false ⇒ Failure( value, Seq( show( value, rule ) ) )
}
}
}
case class Validation[T, H <: HList]( rules: H )(
implicit fold: LeftFolder.Aux[H, T, combine.type, Result[T]]
) {
def validate( value: T ): Result[T] = {
rules.foldLeft( value )( combine )
}
}
object Validation {
object combine extends Poly {
implicit def head[R <: Rule]( implicit definition: Definition[R], show: Show[R] ) = {
use( ( value: R#Value, rule: R ) ⇒ rule.validate( value ) )
}
implicit def success[R <: Rule]( implicit definition: Definition[R], show: Show[R] ) = {
use( ( rule: R, success: Success[R#Value] ) ⇒ {
head.apply( success.value, rule ) )
}
}
implicit def failure[R <: Rule]( implicit definition: Definition[R], show: Show[R] ) = {
use( ( rule: R, failure: Failure[R#Value] ) ⇒ {
rule.validate( failure.value ) match {
case Failure( _, messages ) ⇒
( lens[Failure[R#Value]] >> 'messages ).modify( failure )( _ ++ messages )
case Success( _ ) ⇒ failure
}
} )
}
}
}
Use Validationleads to an implicit error
> Validation( Required[String]() :: Email() :: HNil ).validate( "asdf" )
> [error] could not find implicit value for parameter fold: LeftFolder.Aux[Required[String] :: Email :: HNil, T, combine.type, Result[T]]
> [error] Validation( Required[String]() :: Email() :: HNil ).validate( "asdf" )
> [error] ^
> [error] one error found
I suspected that the implicits ( defintionand show) additional parameters were the cause of the failure , but their temporary removal did not affect the error.
Refresh Working Code Example
source
share