标签: structural-typing

Scala中的结构类型:在细化中使用抽象类型

说我有以下代码:

class Bar { def bar(b:Bar):Boolean = true }
def func(b:Bar) = b.bar(b)    
Run Code Online (Sandbox Code Playgroud)

以上工作正常.该类Bar在第三方库中定义,并且有几个类似的类,每个类都有一个bar方法

class Foo { def bar(f:Foo):Boolean = false }
Run Code Online (Sandbox Code Playgroud)

func我想要定义func使用泛型类型B ,而不是为每个这样的类编写,只要它有一个bar正确签名的方法.

我尝试了以下但它给了我一个错误:

def func[B <: {def bar(a:B):Boolean}](b:B) = b.bar(b) // gives error
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

<console>:16: error: Parameter type in structural refinement may not refer to 
an abstract type defined outside that refinement
def func[B <: {def bar(a:B):Boolean}](b:B) = b.bar(b)
                       ^
Run Code Online (Sandbox Code Playgroud)

但是,如果我执行以下操作,方法定义仍然有效,但调用会产生错误:

def func[B <: {def bar(a:Any):Boolean}](b:B) = b.bar(b) …
Run Code Online (Sandbox Code Playgroud)

scala structural-typing

7
推荐指数
1
解决办法
232
查看次数

为什么不能优化这种隐式转换的情况?

为什么Scala无法优化以下内容:

一个.

implicit def whatever[A](a: A) = new { ... }
Run Code Online (Sandbox Code Playgroud)

至:

class some$generated$name(a: A) {
  ...
}
implicit def whatever[A](a: A) = new some$generated$name(a)
Run Code Online (Sandbox Code Playgroud)

为什么在这种情况下必须使用结构类型?我希望Scala编译器能够执行这种优化,因为写入样式b太丑了(因为,1.逻辑的局部性丢失了,2.你必须不必要地为这些额外的显式类创建名称),而且a的性能要差得多比b.

scala implicit implicit-conversion structural-typing

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

为什么不在这里输入推理?

这个问题出现在我正在编写的模块中,但我做了一个表现出相同行为的最小案例.

class Minimal[T](x : T) {
  def doSomething = x
}

object Sugar {
  type S[T] = { def doSomething : T }
  def apply[T, X <: S[T]] (x: X) = x.doSomething
}

object Error {
  val a = new Minimal(4)
  Sugar(a) // error: inferred [Nothing, Minimal[Int]] does not fit the bounds of apply
  Sugar[Int, Minimal[Int]](a) // works as expected
}
Run Code Online (Sandbox Code Playgroud)

问题是编译器设法找出Minimal(Int)的内部参数,但然后设置Tto 的另一个匹配Nothing,显然不匹配apply.这些肯定是一样的T,因为删除第一个参数会使第二个参数抱怨T未定义.

是否有一些含糊不清意味着编译器无法推断出第一个参数,或者这是一个错误?我可以优雅地解决这个问题吗?

更多信息:此代码是尝试语法糖的简单示例.原始代码试图使|(a)|模数为均值a …

scala structural-typing type-bounds

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

是否可以在Scala中实现不使用反射的`??`(来自C#的空合并运算符)?

我在某处发现了C#null coalescing operator'??'的实现:

implicit def coalescingOperator[T](pred: T) = new {
  def ??[A >: T](alt: =>A) = if (pred == null) alt else pred
}
Run Code Online (Sandbox Code Playgroud)

然后可以像使用a ?? b哪种方式一样使用它if (a == null) b else a.

在反编译类文件后,我看到它生成带反射的代码(在Scala 2.8.1中).

为什么它会生成反射,是否可以修改该代码,以免产生反射?

reflection scala null-coalescing-operator structural-typing

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

如何使用具有通用参数的结构类型?

我有两个案例类

case class StringCaseClass(argument: String)

case class IntCaseClass(argument: Int)
Run Code Online (Sandbox Code Playgroud)

我想定义一个结构类型,它将匹配这两个的伴随对象

type HasApply1 {
  def apply[A, R](argument: A): R
}
Run Code Online (Sandbox Code Playgroud)

这将编译正常,但当我尝试使用它这样

def method(caseClass: HasApply1) {
  // whatever
}

method(StringCaseClass)
Run Code Online (Sandbox Code Playgroud)

我会得到一个编译器错误

found   : StringCaseClass.type
required: WithApply1
            (which expands to)  AnyRef{def apply[A, R](string: A): R}
Run Code Online (Sandbox Code Playgroud)

有没有办法实现这个?如果我重新定义结构类型以具有A和R的具体类型,它将正确编译,但后来我失去了灵活性

generics scala structural-typing

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

结构类型细化和类型相等

我偶然发现了Type.=:=在应用于类型再生时的令人费解的行为.考虑:

import reflect.runtime.universe._
type T1 = AnyRef {
  def apply( name: String ): Unit
  def foo: String
}

type Base = { def apply( name: String ): Unit }
type T2 = Base {
  def foo: String
}
Run Code Online (Sandbox Code Playgroud)

由于Base是一种细化的别名,我会预计,通过将会员进一步完善它foo会产生就好像我所定义的相同类型fooBase.

或者换句话说,我希望T1并且T2表示完全等同的类型.

在大多数情况下,scalac似乎同意.通过示例,我可以传递一个实例T2所在的实例T1:

def f( x: T1 ){}
f( null: T2 ) // scalac does not complain here
Run Code Online (Sandbox Code Playgroud)

反之亦然:

def g( x: T2 ){} …
Run Code Online (Sandbox Code Playgroud)

reflection scala structural-typing

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

Typescript 类型兼容性测试

Typescript 是否支持直接测试结构类型兼容性?

C# 支持is运算符和类型表面IsAssignableFrom(object instance)

if (foo is SomeType) ...
if (SomeType.IsAssignableFrom(foo)) ...
Run Code Online (Sandbox Code Playgroud)

是否有一些直接的方法可以在 Typescript 中执行此类检查,或者我是否必须探测每个所需的成员?

instanceof可能适合手头的情况,但不考虑结构兼容性,而是检查原型链。

是的,我知道,Typescript 的运算符instanceof直接相当于 C# 的is运算符。但我确实从指定结构类型开始。

也许我应该采用庸医方法Object

structural-typing typescript

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

结构细化中的结果类型可能不引用用户定义的值类

当我将包装器定义为值类(扩展AnyVal)时:

class Wrapper(val string: String) extends AnyVal

def wrapperHolder(w: Wrapper): {def wrapper: Wrapper} = new {
  def wrapper: Wrapper = w
}
Run Code Online (Sandbox Code Playgroud)

我对于wrapperHolder有以下编译错误:

Error:(5, 22) Result type in structural refinement may not refer to a user-defined value class
def wrapper: Wrapper = w
Run Code Online (Sandbox Code Playgroud)
  • 为什么它不适用于价值类?

scala compiler-errors compilation structural-typing value-class

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

扩展另一个结构类型的结构类型

为什么不允许出现以下情况?(2.12):

type Foo <: {def foo(): Unit}
type Bar <: {def bar(): Unit} with Foo
Run Code Online (Sandbox Code Playgroud)

对我来说看起来很自然,Bar应该同时具有foo()bar()

types scala structural-typing compound-type

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

Scala中的广义结构类型一致性

我对将特定类型符合更一般结构类型的问题感兴趣.请考虑以下示例:

trait Sup

trait Sub extends Sup

type General = {
   def contra(o: Sub): Unit
   def co(): Sup
   def defaults(age: Int): Unit
   def defaults2(age: Int): Unit
   def defaults3(first: String): Unit
} 

trait Specific {
   def contra(o: Sup): Unit // doesn't conform
   def co(): Sub // conforms
   def defaults(age: Int, name: String = ""): Unit // doesn't conform
   def defaults2(name: String = "", age: Int = 0): Unit // doesn't conform
   def defaults3(first: String = "", last: String = ""): Unit …
Run Code Online (Sandbox Code Playgroud)

scala structural-typing

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