加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如果没有恼人的伪参数来标记类型,Scala隐含的歧义就无法得到解决

发布时间:2020-12-16 09:55:12 所属栏目:安全 来源:网络整理
导读:在 this教程中完成Scala高级类型的一些示例后,我开始玩 (a)暗示和(b)编写一般处理特征子类的方法的技巧 被定义为更高级的类型.我已经在(b) here得到了一个很好的答案,这让我更接近解决下面的问题: 我想创建一个工厂来创建包装的单件容器(集合,列表,数组) 我
在 this教程中完成Scala高级类型的一些示例后,我开始玩
(a)暗示和(b)编写一般处理特征子类的方法的技巧
被定义为更高级的类型.我已经在(b) here得到了一个很好的答案,这让我更接近解决下面的问题:

我想创建一个工厂来创建包装的单件容器(集合,列表,数组)
我传入工厂功能的项目. [即使已经存在Scala
这样做的图书馆,我这样做是为了学习练习.但是,嘿……如果有的话,请告诉我!]

最终的结果应该让我这样做:

scala> var j: Set[String] =  wrapItemInContainer("foo")
j: Set[String] = Set(foo)

scala> var k: List[Int] =  wrapItemInContainer(9)
k: List[Int] = List(9)

我想出的解决方案如下所示.我必须提供一个恼人的虚拟最终参数,以便我可以
帮助编译器找出我想要的容器类型.这是有效的,但我很困惑的事实是
我要将结果赋给(j,k..etc.)的变量的类型签名没有给出
编译足够的信息来确定需要使用哪个隐式定义的ContainerFactory.

这个笨重的解决方案有效:

trait ContainerFactory[M[_]]  { def put[A](x: A): M[A]  }


implicit val factory = new ContainerFactory[List] { def put[A](x: A) = List(x)  }   // factory for List containers
implicit val factory2 = new ContainerFactory[Set] { def put[A](x: A) = Set(x)}    // factory for Set containers

def wrapItemInContainer[ M[A]: ContainerFactory,A](item: A,helper: M[A]) : M[A] = { 
    val c = implicitly[ContainerFactory[M]]                             
    c.put(item)
}

var j: List[Int] =  wrapItemInContainer(9,List(0))

但我真的想要一些没有吵闹的第二个论点:

def wrapItemInContainer[ M[A]: ContainerFactory,A](item: A) : M[A] = { 
    val c = implicitly[ContainerFactory[M[A]]]                             
    c.put(item)
}

var j: List[Int] =  wrapItemInContainer(9)    // this does not work.

我收到此错误:

<console>:17: error: ambiguous implicit values:
 both value factory of type => ContainerFactory[List]
 and value factory2 of type => ContainerFactory[Set]
 match expected type ContainerFactory[M]
       var j: List[Int] =  wrapItemInContainer(9)

任何想法或提示都非常感谢!

-克里斯

解决方法

你需要在M中使工厂协变.见 https://groups.google.com/forum/#!topic/scala-language/dQEomVCH3CI和 https://issues.scala-lang.org/browse/SI-7332.

这编译:

import language.higherKinds

trait Factory[+M[_],A] { def put(x: A): M[A] }

implicit def factory1[A] =
  new Factory[List,A] { def put(x: A) = List(x) }
implicit def factory2[A] =
  new Factory[Set,A] { def put(x: A) = Set(x) }

def wrap[M[_],A](a: A)(
    implicit factory: Factory[M,A]): M[A] =
  factory.put(a)

val j: Set[String] = wrap("foo")
val k: List[Int] = wrap(9)

我冒昧缩短你的名字.我还按照您在how to generically handle Scala Higher-kinded types when coding factories for generating containers of items of type ‘X’收到的建议,在工厂本身制作A类型参数.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读