user3248346
user3248346

Reputation:

How to use Apply for Function Application

I have the following validation logic:

  def one(a : String) : Validation[String, Int] =
    if (a == "one") {
      Success(1)
    } else {
      Failure("Not One")
    }

  def two(a : String) : Validation[String, Int] =
    if (a == "two") {
      Success(2)
    } else {
      Failure("Not Two")
    }

  def validate (a : String) = (one(a) |@| two(a)){_  + _}

According to the Scalaz documentation:

  /**
   * DSL for constructing Applicative expressions.
   *
   * `(f1 |@| f2 |@| ... |@| fn)((v1, v2, ... vn) => ...)` is an alternative to `Apply[F].applyN(f1, f2, ..., fn)((v1, v2, ... vn) => ...)`
   *
   * `(f1 |@| f2 |@| ... |@| fn).tupled` is an alternative to `Apply[F].applyN(f1, f2, ..., fn)(TupleN.apply _)`
   *
   * Warning: each call to `|@|` leads to an allocation of wrapper object. For performance sensitive code, consider using
   *          [[scalaz.Apply]]`#applyN` directly.
   */

How do I convert the validate function to use apply2?

Upvotes: 5

Views: 79

Answers (1)

slouc
slouc

Reputation: 9698

Type constructor for Validate takes two parameters, but Apply can only be parameterized by a type constructor of arity one. You need a special trick called type lambda which allows us to curry the type definition:

def validate(a : String) = Apply[({type λ[Int] = Validation[String, Int]})#λ].apply2(one(a), two(a)){_  + _}

Upvotes: 5

Related Questions