2

鉴于:

abstract class Databases[F[_]]

我怎样才能使这个特征起作用:

// Marker trait signalling the database plugin supports StaticRoles
trait StaticRoles { this: Databases[_] => }

我想确保StaticRoles只混入也扩展的类中Databases,但是我不关心类型参数的具体值F

代码返回:

error: _$1 takes no type parameters, expected: one

这是公平的,但是它返回相同的错误:

trait StaticRoles { this: Databases[_[_]] => }

我也试过:

trait StaticRoles { this: Databases[({type T[X[_]]})#T] => }

这给出了错误:

error: kinds of the type arguments (AnyRef{type T[X[_]]}#T) do not conform to the expected kinds of the type parameters (type F) in class Databases.
       AnyRef{type T[X[_]]}#T's type parameters do not match type F's expected parameters:
       type X has one type parameter, but type _ has none
4

2 回答 2

6

正确的一个是

trait StaticRoles { this: (Databases[F] forSome { type F[_] }) => }

在 Scala 中是否有类型变量 'm forSome { type m[O] <: UpperBound[O] }` 的简写?

并非每个存在类型都可以用下划线表示,或者(在这种情况下)允许用下划线表示。

还有

trait StaticRoles { this: Databases[F forSome { type F[_] }] => }

与前者不同但相同

trait StaticRoles { this: Databases[Any] => }

自从

implicitly[(Databases[F forSome { type F[_] }]) =:= Databases[Any]]

Any实际上是多类的)。

Databases[Any]是一个子类型Databases[F] forSome { type F[_] }

implicitly[Databases[Any] <:< (Databases[F] forSome { type F[_] })]

使用类型投影 ( #) 正确的是

trait StaticRoles { this: Databases[({ type F[_] })#F] => }

Databases[({ type F[_] })#F]也是Databases[F] forSome { type F[_] }(与Databases[Any]for invariant 不可比较Databases)的子类型。

在这三种类型Databases[F] forSome { type F[_] }Databases[Any]Databases[({ type F[_] })#F]只有第一种适用于

trait IO[_]

class Abc extends Databases[IO] with StaticRoles // compiles

//class Abc1 extends StaticRoles // doesn't compile
于 2020-04-14T19:58:32.743 回答
1

我认为你应该定义如下:


  abstract class Databases[F[_]]

  trait StaticRoles[F[_]] { this: Databases[F] =>

    def abc: String
  }

  class Abc extends Databases[IO] with StaticRoles[IO] {
    override def abc: String = ???
  }

注意:如果您删除Databases[IO]并只是这样定义

class Abc extends StaticRoles[IO] {...}

这不会编译。我认为这是您想要实现的目标

于 2020-04-14T19:49:17.877 回答