扩展类时忽略更高种类的类型参数

时间:2018-07-04 05:41:53

标签: scala

正在上课

class Foo[F[_]]

我想实现丰富特质

trait EnrichedFoo extends Foo[_]

但这会导致键入错误:

error: _$1 takes no type parameters, expected: one
  trait EnrichedFoo extends Foo[_]
                                ^

运行示例:https://scalafiddle.io/sf/CkMwDSi/0

编辑:

为什么?我想拥有一种适用于任何参数值的扩充功能,因此我可以编写如下内容:

class MyFoo extends Foo[List] with EnrichedFoo

我必须扩展Foo,因为我希望能够覆盖其某些方法,所以EnrichedFoo不能是自类型(如果有帮助的话)。

3 个答案:

答案 0 :(得分:2)

如果您声明以下内容:

trait Foo {
  type HK[F]
}

trait EnrichedFoo1 extends Foo {
  def enrich1 : Unit = ???
}
trait EnrichedFoo2 extends Foo {
  def enrich2 : Unit = ???
}

abstract class FooClass[HK0[_]] extends Foo {
  type HK[F] = HK0[F]
}

然后用户可以执行以下操作:

class MyFoo1 extends FooClass[List] with EnrichedFoo1
class MyFoo2 extends FooClass[List] with EnrichedFoo2
class MyFoo12 extends FooClass[List] with EnrichedFoo1 with EnrichedFoo2

答案 1 :(得分:2)

为什么不能使用简单的参数就能使用更高种类的参数呢?如果有

class Bar[A] ...

class Baz extends Bar

它只会对Bar的类型参数进行普通类型推断,因此它等效于class Baz extends Bar[Nothing]

  

我必须扩展Foo,因为我希望能够覆盖其某些方法,因此EnrichedFoo不能是自类型(如果有帮助的话)。

这些方法不能提及F,或者您甚至不能在EnrichedFoo中写下它们的签名,对吗?然后为什么不将Foo分成两部分:

trait FooBase {
  // methods not mentioning F
}

trait Foo[F[_]] extends FooBase {
  // other methods
}

trait ExtendedFoo extends FooBase { self: Foo[F] forSome { type F[_] } => 
  // method overrides
}

答案 2 :(得分:1)

您需要使用类型构造函数Foo* -> *中传递具体的类/特征,这意味着它接受类型并返回类型,例如List,它以Int作为类型参数,并返回类型List[Int]

class Foo[F[_]]
trait EnrichedFoo extends Foo[List]