Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Scala中处理高端对象时,类型信息丢失_Scala_Type Inference_Higher Kinded Types - Fatal编程技术网

在Scala中处理高端对象时,类型信息丢失

在Scala中处理高端对象时,类型信息丢失,scala,type-inference,higher-kinded-types,Scala,Type Inference,Higher Kinded Types,我试图分解一些代码,结果不得不使用更高级的类型。 下面的示例效果很好: trait Builder[M[_]] { def build[A]: M[A] def buildPair[A, B]: (M[A], M[B]) = (build[A], build[B]) } class List[A] class BuilderList extends Builder[List] { def build[A] = new List[A] } val l: List[St

我试图分解一些代码,结果不得不使用更高级的类型。 下面的示例效果很好:

trait Builder[M[_]] {
    def build[A]: M[A]
    def buildPair[A, B]: (M[A], M[B]) = (build[A], build[B])
}

class List[A]

class BuilderList extends Builder[List] {
    def build[A] = new List[A]
}

val l: List[String] = (new BuilderList).build[String]

val ll: (List[String], List[Double]) = (new BuilderList).buildPair[String, Double]

defined trait Builder
defined class List
defined class BuilderList
l: List[String] = List@5c7754a7
ll: (List[String], List[Double]) = (List@62874648,List@7b0f6537)
如果我现在想将其应用于具有两个类型参数的类型,比如

class Map[K, V]
我希望能够写作

trait BuilderMap[K] extends Builder[Map[K, _]] {...}
但这当然不起作用,因为Scala中的类型参数不是咖喱

我发现以下技巧让我通过了编译:

trait PartialApplier[F[_, _], K] {
    type PartiallyApplied[_] = F[K, _]
}

class BuilderMap[K] extends Builder[PartialApplier[Map, K]#PartiallyApplied] {
    def build[V] = new Map[K, V]
}
但随后,一些奇怪的效果发生了,我无法找出原因:

scala> val m: Map[Int, String] = (new BuilderMap[Int]).build[String]
m: Map[Int,String] = Map@71da0c64

scala> val mm: (Map[Int, String], Map[Int, Double]) = (new BuilderMap[Int]).buildPair[String, Double]
<console>:21: error: type mismatch;
 found   : (Map[Int, _], Map[Int, _])
 required: (Map[Int,String], Map[Int,Double])
   val mm: (Map[Int, String], Map[Int, Double]) = (new BuilderMap[Int]).buildPair[String, Double]
scala>val m:Map[Int,String]=(新的BuilderMap[Int])。build[String]
m:Map[Int,String]=Map@71da0c64
scala>valmm:(Map[Int,String],Map[Int,Double])=(新的BuilderMap[Int])。buildPair[String,Double]
:21:错误:类型不匹配;
已找到:(映射[Int,307;],映射[Int,307;])
必需:(映射[Int,String],映射[Int,Double])
val mm:(Map[Int,String],Map[Int,Double])=(新的BuilderMap[Int])。buildPair[String,Double]
当我使用
partialapplicater
技巧时,在更高级的trait
Builder
中定义的函数似乎丢失了一些类型信息


有没有办法让这一切顺利进行?也许
partialapplicater
技巧不是正确的方法

type PartiallyApplied[]=F[K,]
中的示例中,下划线没有指定相同的类型

如果将
partialapplicator
定义为

trait PartialApplier[F[_, _], K] {
  type PartiallyApplied[V] = F[K, V]
}

此外,您可以完全避免使用
partialapplicater
,并定义
Builder
类型参数如下:

class BuilderMap[K] extends Builder[({ type L[V] = Map[K, V] })#L] {
  def build[V] = Map.empty[K, V]
}

这是一个完美的答案。谢谢