为采用带有类型参数的方法的类型类定义构造函数?

Defining a constructor for a typeclass that takes a method with a type parameter?

我遇到的情况是 none 我知道的解决方案感觉不错。我正在尝试定义一个类型类,如下例所示,它有一个抽象类型 S,必须实现另一个类型类(未显示)Valid[A]。感觉最简单的方法是创建一个 apply 构造函数,它将强制用户输入 S 并自动为 sIsValid.[=19 引入隐式实例=]

这个问题是函数 changeType 有一个类型参数。尽管进行了一些谷歌搜索,但我还没有想出如何为采用类型参数的函数编写类型注释(这可能是因为 Scala 似乎不允许带有类型参数的匿名函数)。我在这里的方法看起来是明智的吗?如果我可以为 changeType 提供类型注释,那么类型类用户仍然可以将非匿名函数传递给 apply 构造函数,这似乎是一个最令人满意的解决方案。

abstract class IsTC[A[_], T] {
  // type S is an abstract type rather than type parameter, but must implement Valid[A]
  type S
  implicit val sIsValid: Valid[S]

  def get(self: A[T], i: Int): T
  def changeType[_T]: A[_T]
}
object IsTC {
  def apply[A[_], T, _S](
    fget: (A[T], Int) => T,
    fchangeType:  // what should this type annotation be?
  ): IsTC[A, T] { type S = _S } = new IsTC[A, T] {
    type S = _S
    def get(self: A[T], i: Int) = fget(self, i)
    def changeType[_T]: A[_T] = fchangeType[_T]
  }
}

任何 help/thoughts 感激不尽。

Scala 2 不支持多态函数。多态可以是方法,而不是值。和函数 are 值。可以用包装器模拟多态函数

// for [A] => (a: A) => B[A]
trait Poly {
  def apply[A](a: A): B[A]
}

// for [A <: U] => (a: A) => B[A]
trait Poly[U] {
  def apply[A <: U](a: A): B[A]
}

喜欢 shapeless.Poly。他们泛化普通函数

trait Function[A, B] {
  def apply(a: A): B
}

尝试

object IsTC {
  def apply[A[_], T, _S](
                          fget: (A[T], Int) => T,
                          fchangeType: FchangeType[A]
                        ): IsTC[A, T] { type S = _S } = new IsTC[A, T] {
    override type S = _S
    override implicit val sIsValid: Valid[_S] = ???
    override def get(self: A[T], i: Int) = fget(self, i)
    override def changeType[_T]: A[_T] = fchangeType[_T]
  }
}

trait FchangeType[A[_]] {
  def apply[X]: A[X]
}

Dotty has polymorphic functions [A <: U] => (a: A) => f[A](a) of polymorphic function types [A <: U] => A => B[A] but there is implementation restriction: polymorphic function types must have a value parameter so you can't have polymorphic function type [X] => A[X] ( 类型为 lambda [X] =>> A[X]) 目前甚至在那里。

另外(除了用包装器模拟)一些多态类型可以通过存在类型来表达:[A] => B[A] => C(常量 C)实际上是 B[_] => C.

这是因为∀a: (B(a) => C)(∃a: B(a)) => C.