Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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_Types_Implicits - Fatal编程技术网

Scala视图应用程序谜题

Scala视图应用程序谜题,scala,types,implicits,Scala,Types,Implicits,假设我们有以下两个特点: trait Foo[A] { def howMany(xs: List[A]) = xs.size } trait Bar 以及从第二个到第一个的隐式转换: implicit def bar2foo[A](bar: Bar) = new Foo[A] {} 我们创建一个条和一个整数列表: val bar = new Bar {} val stuff = List(1, 2, 3) 现在,我希望以下方法能够奏效: bar howMany stuff 但事实并非如此

假设我们有以下两个特点:

trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar
以及从第二个到第一个的隐式转换:

implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
我们创建一个
条和一个整数列表:

val bar = new Bar {}
val stuff = List(1, 2, 3)
现在,我希望以下方法能够奏效:

bar howMany stuff
但事实并非如此:

scala> bar howMany stuff
<console>:13: error: type mismatch;
 found   : List[Int]
 required: List[A]
              bar howMany stuff
                          ^
但确实如此(至少在2.9.2和2.10.0-RC2上):

这会导致一些非常奇怪的行为,例如for

我有三个(密切相关的)问题:

  • 是否有一种简单的方法(即,不涉及添加具有适当名称的假方法)可以在上面的原始案例中正确应用视图
  • 有人能提供说明这种行为的规格说明吗
  • 假设这是预期的行为,它有任何意义吗

  • 我也非常感谢与之前关于这个问题的讨论的任何链接——我在谷歌的运气不太好。

    用以下内容替换您的Foo:

    trait Foo[]{def howMany(xs:List[])=xs.size}


    它是有效的,这对我来说也更有意义,因为你对a绝对不感兴趣。

    你的隐式转换似乎正是你告诉它做的

    implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
    
    将条形图转换为新的
    Foo[a]
    对象。反过来说

    scala> bar howMany stuff
    <console>:13: error: type mismatch;
     found   : List[Int]
     required: List[A]
                  bar howMany stuff
    
    然后它会给你你想要的结果

    scala> bar howMany stuff
    res0: Int = 3
    
    也可以在隐式函数上定义视图

    trait Foo[A] { def howMany(xs: List[A]) = xs.size }
    trait Bar
    
    implicit def bar2foo[A](bar: Bar) = new Foo[Int] {}
    
    val bar = new Bar {}
    val stuff = List(1, 2, 3)
    

    就我个人而言,我认为在函数上定义它更简洁。

    这似乎是一个bug,因此我的答案是:

  • 搜索针对Scala编译器报告的simliar错误,如果未找到,则报告新错误
  • 规范的这一部分在本例中似乎并不重要,因为它没有讨论类型推断
  • 对我来说没有任何意义

  • 注:在2.8.1中,将虚拟方法添加到Bar中的变通方法无法使其编译。

    这虽然很难看,但似乎有效:

    (bar: Foo[Int]) howMany stuff
    

    供大家参考,这可能只是一个bug。您知道的方式是错误消息:

    <console>:13: error: type mismatch;
     found   : List[Int]
     required: List[A]
    
    :13:错误:类型不匹配;
    找到:列表[Int]
    必需:列表[A]
    
    列表[A]不是实类型-它是应用于自身类型参数的列表。这不是一个需要的类型,因为它不是一个可以表达的类型

    [编辑-现在太早了,谁知道我在说什么。忽略上面的内容,但你仍然可以点击链接。]


    与此相关的问题是。

    这在特定的简化情况下有效,但一般来说,我关心的是
    A
    ——例如,在问题中链接的Scalaz问题的解决方案中。我想要的是“明显的”行为,即。,对于
    Foo
    一个
    参数,该参数将根据
    多少个
    的参数进行推断。这显然是可能的,因为我可以通过向
    Bar
    添加一个(完全任意定义的)伪
    howmounty
    方法来实现。
    trait Foo[A] { def howMany(xs: List[A]) = xs.size }
    trait Bar
    
    implicit def bar2foo[A](bar: Bar) = new Foo[Int] {}
    
    val bar = new Bar {}
    val stuff = List(1, 2, 3)
    
    (bar: Foo[Int]) howMany stuff
    
    <console>:13: error: type mismatch;
     found   : List[Int]
     required: List[A]