标签: structural-typing

结构类型和原语

当我发现看起来像个臭虫的时候,我正在玩Scala的结构类型.这是我的代码:

type toD = { def toDouble: Double }
def foo(t: toD) = t.toDouble
foo(5)
Run Code Online (Sandbox Code Playgroud)

我收到了这个错误:

java.lang.NoSuchMethodException
at scala.runtime.BoxesRunTime.toDouble(Unknown Source)
at .foo(<console>:9)
at .<init>(<console>:11)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Unknown Source)
Run Code Online (Sandbox Code Playgroud)

首先,我不知道为什么这不起作用.其次,奇怪的是代码编译得很好并在运行时抛出一个异常,说该方法实际上并不存在.

有没有人对此有解释?

scala structural-typing

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

使用Scala的结构类型创建更具体的隐式

据我所知,集合库中没有共享特征来定义map方法(很可能是因为有不同的签名map).

我有一个可观察的值(想想一个ui系统中的属性),它有一个change事件.可以使用map方法映射可观察值.

但是,当我们使用已经有map方法的类型时,我们应该能够使用内置方法map.

所以代替:

prop map { x => 
  x map { actualX =>
   //do something
  }
}
Run Code Online (Sandbox Code Playgroud)

我想这样使用它:

prop map { actualX =>
  //do something
}
Run Code Online (Sandbox Code Playgroud)

我有一个简化的测试用例.首先是我使用的不同部分:

// leaving out the observable part
trait ObservableValue[T] {
  def value: T
}

trait LowerPriorityImplicits {
  // default implementation that adds a regular map method
  implicit class RichObservableValue1[A](o: ObservableValue[A]) {
    def map[B](f: A => B): ObservableValue[B] = new ObservableValue[B] {
      def value …
Run Code Online (Sandbox Code Playgroud)

types scala typeclass implicit-conversion structural-typing

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

Go中的结构类型和多态性 - 编写一种可以在具有相同字段的两种类型上操作的方法

在开始使用其他语言(如Scala和OCaml)进行结构化输入后,我开始研究Go,并且我正在尝试映射语言之间的一些惯用技术.请考虑以下类型

type CoordinatePoint struct {
    x int
    y int
    // Other methods and fields that aren't relevant
}

type CartesianPoint struct {
    x int
    y int
    // Other methods and fields that aren't relevant
}
Run Code Online (Sandbox Code Playgroud)

假设我们想编写一种方法,对这两种类型进行操作以计算它们的极坐标表示,func ConvertXYToPolar(point XYPoint) PolarPoint.如果CartesianPointCoordinatePoint类型定义了xy字段的getter和setter方法,我们可以将它们定义XYPoint为与这些方法的公共接口,允许我们对这两种类型进行操作,但是就目前而言,接口不能声明字段,只能声明方法.

基于此,我有几个问题:

  1. 在Go中处理这个问题的惯用方法是什么?
  2. 可以在不修改现有类型的情况下完成吗?
  3. 我们可以保留类型安全性,即避免定义ConvertXYToPolar而不使用空接口类型作为参数并手动转换?
  4. 如果接口和隐式接口满意度是Go中多态性的主要工具,那么接口定义中字段的禁止是否受到限制?
  5. 是否通常在结构上定义了getter/setter方法来规避这种限制?
  6. 设计决策背后是否有一个令人信服的理由支持接口定义中的字段?

我发现嵌入式类型的简单性,隐式接口满足性和基于接口的多态性是一种非常简单且吸引人的技术组合,可以提高代码的可重用性和可维护性,但禁止接口定义中的字段使得Go的结构类型化能力在某种程度上受限于我的观点.我错过了一个简单的解决方案?

go structural-typing

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

在scala中定义基于duck typing的泛型类型?

我知道我可以定义鸭子打字generics如下

trait MyTrait[A <: {def someMethod(key: String): String}]
Run Code Online (Sandbox Code Playgroud)

但是我不想string在我的trait定义中指定那么大.

我怎么能把它分成两部分(我希望我能拥有):

type A = B <: {def someMethod(key: String): String}

trait MyTrait[A]
Run Code Online (Sandbox Code Playgroud)

generics scala structural-typing

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

为什么隐式非指针方法不满足接口?

假设我们有这样的理解,

用于类型明确的方法定义X,GO编译器隐式定义了相同的方法类型*X反之亦然,如果我声明,

func (c Cat) foo(){
  //do stuff_
} 
Run Code Online (Sandbox Code Playgroud)

并声明,

func (c *Cat) foo(){
  // do stuff_
}
Run Code Online (Sandbox Code Playgroud)

然后GO编译器给出错误,

Compile error: method re-declared
Run Code Online (Sandbox Code Playgroud)

这表明,指针方法是隐式定义的,反之亦然


在下面的代码中,

package main

type X interface{
  foo();
  bar();
}

type Cat struct{

}

func (c Cat) foo(){
  // do stuff_
}

func (c *Cat) bar(){
  // do stuff_
}

func main() {
  var c Cat
  var p *Cat
  var x X

  x = p // OK; *Cat has explicit …
Run Code Online (Sandbox Code Playgroud)

methods interface go structural-typing

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

结构类型不是鸭子类型

正如 TypeScript手册中提到的:

TypeScript 的核心原则之一是类型检查侧重于值的形状。这有时被称为“鸭子类型”或“结构子类型”。在 TypeScript 中,接口扮演着命名这些类型的角色,...


我的理解是,上述核心原则与Duck 类型无关,而是与结构类型有关,因为 TypeScript 是静态类型语言。

正如维基中提到的:它要求类型检查推迟到运行时,并通过动态类型或反射来实现......对象的适用性取决于某些方法和属性(具有适当含义)的存在,而不是对象的实际类型。

如何理解上述TypeScript的核心原理?

javascript type-systems duck-typing structural-typing typescript

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

作为结构类型成员的值类

这是简化的代码:

class Value(val value: Int) extends AnyVal

val v = new Value(1)

val x = new { val f: Int = v.value }
println(x.f)

val y = new { val f: Value = v }
println(y.f)
Run Code Online (Sandbox Code Playgroud)

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

val y = new { val f: 值 = v }

我不明白。既然Int也是一个值类,为什么Int可以用作成员,而我的值类Value却不能?为什么scala定义了这个限制?如何在结构类型中使用用户定义的值vlass?

scala structural-typing value-class

5
推荐指数
0
解决办法
171
查看次数

协议的所有基础都必须是协议——typing.MutableMapping 不是协议吗?

我想为自定义映射类定义一个类型协议。这个类需要与 a 非常相似,除了它除了那些定义为抽象方法(特别是)MutableMapping之外还有几个附加方法,并且我还想提前指定自定义映射类的任何实现必须使用哪些类型作为键和值。collections.abc.MutableMapping.copy()

读完PEP 544后,我想我应该能够做到这一点:

from typing import Hashable, MutableMapping, Protocol, TypeVar


TVarMapProt = TypeVar("TVarMapProt", bound="VariableMappingProtocol")


class VariableMappingProtocol(MutableMapping[Hashable, int], Protocol):
    """
    Protocol for the type behaviour of a class which
    acts basically like a dict of int objects.
    """

    def copy(self: TVarMapProt) -> TVarMapProt:
         # TODO replace return type with Self if PEP 673 goes through
        ...
Run Code Online (Sandbox Code Playgroud)

我的想法是,在我的代码中,我可以声明需要一个类型VariableMappingProtocol,然后用户必须使用自己定义的类,以避免输入错误:

TCusVarMap = TypeVar("CusVarMap", bound="CustomVariableMapping")


class CustomVariableMapping
    """Defines all the methods that a MutableMapping does, …
Run Code Online (Sandbox Code Playgroud)

python abc structural-typing mypy python-typing

5
推荐指数
0
解决办法
568
查看次数

为什么这种结构类型绑定不能按预期工作?

我正在尝试编写一个简单的辅助方法,它接收可以关闭的东西和一些接收前者的函数,并确保在执行函数后关闭"closeable".

例如,我想像这样使用它:

  closing(new FileOutputStream("/asda"))(_.write("asas"))
Run Code Online (Sandbox Code Playgroud)

我的意思是

object Helpers {

  def closing[T <: { def close }](closeable: T)(action: T => Unit): Unit =
    try action apply closeable finally closeable close

}
Run Code Online (Sandbox Code Playgroud)

但是在尝试编译这个简单的测试时:

object Test {

  import Helpers._

  closing(new FileOutputStream("/asda"))(_.write("asas"))

}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨:

推断类型参数[java.io.FileOutputStream]不符合方法结束的类型参数bounds [T <:AnyRef {def close:Unit}]

有什么想法吗?

scala structural-typing

4
推荐指数
2
解决办法
531
查看次数

可穿越式结构打字

我有这个方法:

scala> def foo(traversable: Traversable[{def toByte: Byte}]) = {
     | traversable.map(_.toByte)
     | }
foo: (traversable: Traversable[AnyRef{def toByte: Byte}])Traversable[Byte]
Run Code Online (Sandbox Code Playgroud)

但是当我这样称呼时:

scala> foo(List(1,2,3))

我明白了:

java.lang.NoSuchMethodException
    at scala.runtime.BoxesRunTime.toByte(Unknown Source)
    at $anonfun$foo$1.apply(<console>:8)
    at $anonfun$foo$1.apply(<console>:8)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194)
    at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
    at scala.collection.immutable.List.foreach(List.scala:45)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:194)
    at scala.collection.immutable.List.map(List.scala:45)
    at .foo(<console>:8)
Run Code Online (Sandbox Code Playgroud)

但是,当我做这样的事情时:

scala> 1.toByte
res1: Byte = 1
Run Code Online (Sandbox Code Playgroud)

有用.

我可能错过了一些基本的东西,我忽略了它,但我怎么能让这个工作呢?

scala structural-typing

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