输入implicits的同义词?

时间:2018-03-18 23:00:28

标签: scala types functional-programming higher-order-functions higher-kinded-types

您是否可以为采用隐式参数的函数创建类型同义词?

缩短

之类的内容
def findOnlyOne(f: Node => Boolean)(n: Node)(implicit errorType: String => ValidationError): Either[ValidationError, Node] = ...

如果errorType不是隐式的,则可以是:

type ValidationF = (Node => Boolean) => Node => (String => U) => Either[U, Node]
findOnlyOne: ValidationF = f => n => onErr => ...

我猜你不能,因为与其他类型不同,隐式参数的名称对它很重要,所以你需要更高级的顺序,比如

ImplicitFunction[myImplicitParam, T]

代表implicit myImplicitParam: T

难以谷歌因为“类型”,“隐含”,“同义词”的组合不传达我正在寻找制作包含隐式类型的类型同义词......

1 个答案:

答案 0 :(得分:2)

我认为SAM已经或多或少地提供了你想要的东西:

trait Node
trait ValidationError
import scala.util.Either

abstract class ValidationF {
  // single abstract method without implicits
  def apply_impl(
    f: Node => Boolean, 
    n: Node, 
    errorType: String => ValidationError
  ): Either[ValidationError, Node]

  // actual `apply` with implicits
  def apply
    (f: Node => Boolean)
    (n: Node)
    (implicit errorType: String => ValidationError)
  : Either[ValidationError, Node] = {
    apply_impl(f, n, errorType)
  }
}

val findOnlyOne: ValidationF = 
  (f, n, onErr) => (??? : Either[ValidationError, Node])

它只适用于tupled参数,不适用于curried函数的长链,但是......

如果你坚持使用curried函数初始化这些东西,那么你可以为它创建一个单独的工厂方法:

object ValidationF {
  def apply(
    curried: 
      (Node => Boolean) => 
      Node => 
      (String => ValidationError) => 
      Either[ValidationError, Node]
  ): ValidationF = new ValidationF {
    def apply_impl(
      f: Node => Boolean, 
      n: Node, 
      errorType: String => ValidationError
  ): Either[ValidationError, Node] = {
      curried(f)(n)(errorType)
    }
  }
}

val findOnlyTwo = ValidationF(f => n => onErr => 
  (??? : Either[ValidationError, Node])
)

它只比: ValidationF = ...版本长一个字符。