小编cfc*_*hou的帖子

隐式<:<help如何查找类型参数

在我阅读时会出现几个问题.3.3.2从Joshua的Scala深度捕获类型约束.摘自本书的例子:

scala> def peek[C, A](col: C)(implicit ev: C <:< Traversable[A]) = (col.head, col)
peek: [C, A](col: C)(implicit ev: <:<[C,Traversable[A]])(A, C)

scala> peek(List(1, 2, 3))
res9: (Int, List[Int]) = (1,List(1, 2, 3))
Run Code Online (Sandbox Code Playgroud)

通过第一个参数列表C发现它似乎很简单List[Int].如何<:<通过方差强制类型约束在本书中进行了解释.但我不太明白这有多大帮助A.

我的理解是,从第一个参数列表,scala发现C: List[Int],然后它寻找implicit ev: <:<[List[Int], Traversable[A]].目前A仍然未知.它"拉动"两个暗示conforms[List[Int]]conforms[Traversable[A]]匹配ev.在任一情况下,以满足方差,List[Int] <: Traversable[A]必须被满足,这导致这一发现AInt.

它是否像我在这里描述的那样工作?特别是关于如何/何时A推断.

scala implicit

22
推荐指数
1
解决办法
478
查看次数

在Scala中,为什么不为类型参数发出未经检查的警告?

我一般都了解什么类型的擦除以及为什么我们会遇到未经检查的警告.但是,我不明白为什么在以下情况下只发出一个未经检查的警告:

class A[K] {
  def receive: PartialFunction[Any, Unit] = {
    case ds: List[Double] =>  // unchecked warning
      println("* List[Double]")
    case kx: Vector[K] =>      // no unchecked warning
      println("* Vector[K]")
  }
}

object TestApp extends App {
  val a = new A[Int]
  a.receive(List("bar"))
  a.receive(Vector("foo"))
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,两个接收呼叫都匹配案例条款.编译器确实对第一个子句发出警告:

警告:类型模式中的非变量类型参数Double [Double]未选中,因为它已被擦除消除.

我知道TypeTag [T]可以用来实现更好的类型安全性.但我关注的是为什么没有为第二个案件条款发出未经检查的警告.据我所知,类型参数K也被删除,并根据Java Generics FAQ

当编译器找到目标类型为参数化类型或类型参数的强制类型转换时,也会报告"未选中"警告

所以我想知道为什么不存在未经检查的警告?

jvm scala type-erasure

14
推荐指数
1
解决办法
194
查看次数

有什么阻止优化尾递归?

我正在使用动态编程解决Haskell中的背包问题.我的第一次尝试是建立一个二维表.但是当输入很大时(例如100*3190802表),内存容易被炸毁.

知道任何给定的行i只依赖于行(i - 1),我改为编写一个函数,希望利用尾递归:

import Data.Vector (Vector, (!))
import qualified Data.Vector as V

-- n items, k capacity, vs values, ws weights
ans:: Int -> Int -> Vector Int -> Vector Int -> Int
ans n k vs ws =
    let row = initRow k vs ws
    in  row ! k

initRow :: Int -> Vector Int -> Vector Int -> Vector Int
initRow k vs ws = itbl 1 $ V.replicate (k + 1) 0 …
Run Code Online (Sandbox Code Playgroud)

haskell tail-recursion knapsack-problem lazy-evaluation

9
推荐指数
1
解决办法
442
查看次数

在Scala中隐含对象

我对Joshua Suareth的书Scala中的"5.1.3隐式解决方案"中的描述感到困惑,第100页:

Scala对象不能包含implicits的伴随对象.因此,必须从外部作用域提供与该对象类型的隐式作用域所需的对象类型相关的隐含.这是一个例子:

scala> object Foo {
     |   object Bar { override def toString = "Bar" }
     |   implicit def b : Bar.type = Bar 
     |}
defined module Foo
scala> implicitly[Foo.Bar.type]
res1: Foo.Bar.type = Bar
Run Code Online (Sandbox Code Playgroud)

但是我在REPL中隐藏了对象Bar:

scala> object Foo {
     |   implicit object Bar {
     |     override def toString = "isBar" }
     | }
defined module Foo
scala> implicitly[Foo.Bar.type]
res0: Foo.Bar.type = isBar
Run Code Online (Sandbox Code Playgroud)

似乎它不需要在外部范围中定义隐式.或者我认为约书亚的意思完全错了?

scala object implicit

6
推荐指数
1
解决办法
950
查看次数

Scala特征中的抽象私有字段

我碰巧发现不允许在特征中使用抽象的私有字段,也就是说,

trait A1 {
    //private val a: Int         // Not allowed
    protected val b: Int         // OK
}
Run Code Online (Sandbox Code Playgroud)

如果私有字段是构造函数参数,那么对抽象类做这样的事似乎是可以的,也就是说,

abstract class A2 (private val i: Int) // OK
Run Code Online (Sandbox Code Playgroud)

所以我猜一个特征没有构造函数参数,因此没有办法初始化它们,因此不允许使用抽象的私有字段.

如果它们是"受保护的",则子类可以使用预先初始化的字段初始化它们.此方法允许子类查看这些字段.

如果我只想初始化它们并在之后隐藏它们,如下例所示,该怎么办?

object holding {
    trait trick {
        protected val seed: Int                     // Can't be private
        final def magic: Int = seed + 123
    }

    trait new_trick extends trick {
        def new_magic: Int = magic + 456
        def the_seed: Int = seed                    // [1]
    }

    def play: new_trick = new { …
Run Code Online (Sandbox Code Playgroud)

scala traits

6
推荐指数
2
解决办法
7833
查看次数

由Ordering [T]限定的类型参数T

在实现可排序的数据结构时,我正在考虑做这样的事情:

trait MaxHeap[T <: Ordering[T]] {
    def insert(e: T): Unit
    ...
}
Run Code Online (Sandbox Code Playgroud)

但这对MaxHeap [Int]等类型不起作用.在标准集合库中,集合的元素类型T不受限制.相反,为需要将T转换为Ordering [T]的方法提供了隐式,例如

trait Seq[+A] extends ... {
    // it's Ordering[B], not Ordering[A], but the idea is the same.
    def max[B >: A](implicit cmp: Ordering[B]): A
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我的类/特性中有很多方法涉及比较,有没有办法指定类/特征的元素类型是可比较的,这样我就不需要声明这些方法的含义?

scala implicit

5
推荐指数
1
解决办法
1309
查看次数

Quasar光纤中的阻塞IO会阻塞其线程池中的线程吗?

据我所知,在Akka,所有演员都安排在一个线程池中.太多的actor同时执行阻塞IO,每个阻塞调用阻塞一个线程,导致线程中断.

现在我在JVM上看一个有趣的光纤实现 - Quasar允许大量用户线程 - 光纤 - 并使用线程池来安排它们.但是,我想知道当许多光纤称为传统阻塞API时是否有好处.

我不认为它会有所帮助,因为阻塞API仍然会阻塞系统线程,而Quasar无法神奇地将其转换为仅阻挡光纤.这只是我的猜测,如果我错了,请纠正我.

java fibers actor akka quasar

5
推荐指数
1
解决办法
2074
查看次数

ScalaCheck 中的 suchThat 用法

我正在通过阅读 ScalaCheck 的代码来学习 scala,发现许多组合器都以suchThat. 然而,在很多情况下,这样的做法看起来并不是很有必要。我想知道为什么它们要这样设计。以下是GitHub上的一些摘录:

Example 1.

/** Picks a random value from a list */
def oneOf[T](xs: Seq[T]): Gen[T] =
    choose(0, xs.size-1).map(xs(_)).suchThat(xs.contains)
Run Code Online (Sandbox Code Playgroud)

map从 xs 中选择一个元素,因此xs.contains看起来是多余的。

--

Example 2.

def containerOfN[C[_],T](n: Int, g: Gen[T])
    (implicit evb: Buildable[T,C], evt: C[T] => Traversable[T]): Gen[C[T]] =
    sequence[C,T](Traversable.fill(n)(g)) suchThat { c =>
      c.size == n && c.forall(g.sieveCopy)
    }
Run Code Online (Sandbox Code Playgroud)

c.size == n既然成功sequence返回的长度为 n ,为什么需要这样做呢?

--

Example 3.

/** Generates a string of alpha characters */ …
Run Code Online (Sandbox Code Playgroud)

scala scalacheck

4
推荐指数
1
解决办法
1057
查看次数