【发布时间】:2016-10-25 05:19:16
【问题描述】:
我想知道如何(安全地)在 Scala 的左侧为表达式添加类型归属。
在使用复杂的 for 表达式时,推断的类型通常难以遵循,或者可能会偏离轨道,因此最好在 for {..} 块中注释表达式,以检查您和编译器是否一致。使用Eff monad的说明性代码草图:
for {
e1: Option[(Int, Vector[Int])] <- complexCalc
e2 <- process(e1)
} yield e2
def complexCalc[E]: Eff[E, Option[(Int, Vector[Int])]] = ???
但是,这与 Scala 对 for 表达式的 LHS 上的模式匹配的支持相冲突。
- 正如 earlier question 中所讨论的,Scala 将类型归属
: Option[(Int, Vector[Int])]视为要匹配的模式。 - 编译器有 irrefutable 模式的概念,它们总是匹配的。相反,refutable 模式可能不匹配,因此当用于 for 表达式时,righthand-side expression must provide a
withFiltermethod to handle the non-matching case。 - 由于longstanding compiler bug/limitation,元组和其他常见的constructor patterns 似乎永远不会被视为无可辩驳的。
最终结果是,添加类型归属会使 LHS 模式看起来可反驳,并且需要在 RHS 上定义 filter 操作。症状是编译器错误,例如 value filter is not a member of org.atnos.eff.Eff[E,Option[(Int, Vector[Int])]]。
如果有任何句法形式可用于将类型归属于包含元组的中间表达式,在 for 表达式中,而不会遇到可反驳的模式匹配?
【问题讨论】:
-
您能举一个例子(complexCalc 和 process)来证明这一点吗?您链接到的上一个问题没有讨论该位置的类型注释。你是通过
Anys 吗? -
你不能归属于右手边吗?
for { e <- (complexCalc : Eff[E, Option[(Int, Vector[Int])]]) ; ... } yield e2之类的东西? -
@PeterNeyens 是的。 RHS 类型更复杂,因为它们包含 monadic 包装器(例如上面的
Eff[E, <lhs>]),因此希望找到一种方法来注释更简单的 LHS “有效负载”类型
标签: scala filter pattern-matching monads type-inference