标签: structural-typing

将Scala结构类型与抽象类型一起使用

我正在尝试定义一个结构类型,定义任何具有"add"方法的集合(例如,java集合).使用这个,我想定义一些对某个集合进行操作的高阶函数

object GenericTypes {
  type GenericCollection[T] = { def add(value: T): java.lang.Boolean}
}

import GenericTypes._
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection[X]] {
    def map[V](fn: (T) => V): CollectionType[V]
    ....
}

class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List]
Run Code Online (Sandbox Code Playgroud)

这不会编译与以下错误

error: Parameter type in structural refinement may not refer to abstract type defined outside that same refinement 
Run Code Online (Sandbox Code Playgroud)

我尝试删除GenericCollection上的参数并将其放在方法上:

object GenericTypes {
  type GenericCollection = { def add[T](value: T): java.lang.Boolean}
}
import GenericTypes._
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection]

class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List]
Run Code Online (Sandbox Code Playgroud)

但我得到另一个错误: …

scala structural-typing

10
推荐指数
1
解决办法
1952
查看次数

Clojure协议与Scala结构类型

在观看了Rich Hickey对Clojure 1.2 协议的采访,并且对Clojure知之甚少之后,我对Clojure协议提出了一些问题:

  • 它们是否打算与Scala中的结构类型做同样的事情?协议对结构类型(性能,灵活性,代码清晰度等)有什么好处?它们是通过反思实现的吗?
  • 有关与Scala的互操作性的问题:可以使用协议而不是Scala中的结构类型吗?它们可以在Scala中扩展(如果'扩展'术语可以应用于协议)吗?

scala language-design protocols clojure structural-typing

10
推荐指数
3
解决办法
2315
查看次数

OCaml,Scala和Go的结构类型实现

在研究结构类型时,我发现以下帖子描述了Go中的接口如何在运行时转换为方法查找表.帖子中描述的过程似乎 Scala的可选结构类型系统和Java语言的White Oak扩展所描述的反射和生成技术大不相同.

是否有任何深入的资源讨论如何在OCaml中实现结构类型?我对任何有关标称类型系统的优化或运行时性能比较的讨论特别感兴趣.

ocaml types scala go structural-typing

10
推荐指数
1
解决办法
766
查看次数

为什么Haskell没有结构类型的记录?

我听说Haskell被描述为具有结构类型.据我了解,记录是一个例外.例如foo,HRec2即使在某些类型的东西中也不能调用它们,HRec并且HRec2在它们的字段中只是名义上不同.

data HRec = HRec { x :: Int, y :: Bool }
data HRec2 = HRec2 { p :: Int, q :: Bool }

foo :: HRec -> Bool
Run Code Online (Sandbox Code Playgroud)

是否有一些解释拒绝将结构类型扩展到包括记录在内的所有内容?

是否存在结构类型的静态类型语言,即使是记录?对于所有静态类型语言,我可以阅读一下这个问题吗?

haskell record structural-typing

9
推荐指数
2
解决办法
1712
查看次数

Scala - 如何定义引用自身的结构类型?

我正在尝试编写一个泛型interpolate方法,该方法适用于任何具有两种方法的类型,a *和a +,如下所示:

trait Container {
  type V = {
    def *(t: Double): V
    def +(v: V): V
  }

  def interpolate(t: Double, a: V, b: V): V = a * (1.0 - t) + b * t
}
Run Code Online (Sandbox Code Playgroud)

这不起作用(在Scala 2.8.0.RC7上),我收到以下错误消息:

<console>:8: error: recursive method + needs result type
           def +(v: V): V
                        ^
<console>:7: error: recursive method * needs result type
           def *(t: Double): V
                             ^
Run Code Online (Sandbox Code Playgroud)

如何正确指定结构类型?(或者有更好的方法吗?)

scala structural-typing

8
推荐指数
1
解决办法
871
查看次数

为什么接口必须用Java声明?

有时我们有几个类具有相同签名的某些方法,但是它们与声明的Java接口不对应.例如,两者JTextFieldJButton(在其他几个中 javax.swing.*)都有一种方法

public void addActionListener(ActionListener l)
Run Code Online (Sandbox Code Playgroud)

现在,假设我希望对具有该方法的对象执行某些操作; 那么,我想要一个界面(或者自己定义它),例如

  public interface CanAddActionListener {
      public void addActionListener(ActionListener l);
  }
Run Code Online (Sandbox Code Playgroud)

所以我可以写:

  public void myMethod(CanAddActionListener aaa, ActionListener li) {
         aaa.addActionListener(li);
         ....
Run Code Online (Sandbox Code Playgroud)

但是,遗憾的是,我不能:

     JButton button;
     ActionListener li;
     ...
     this.myMethod((CanAddActionListener)button,li);
Run Code Online (Sandbox Code Playgroud)

这个演员是非法的.编译器知道JButton 不是 a CanAddActionListener,因为类没有声明实现该接口...... 但是它"实际"实现了它.

这有时会带来不便 - 而Java本身已经修改了几个核心类来实现由旧方法构成的新接口(String implements CharSequence例如).

我的问题是:为什么会这样?我理解声明一个类实现接口的实用程序.但无论如何,看看我的例子,为什么编译器不能推断出类JButton"满足"接口声明(查看它内部)并接受转换?这是编译器效率的问题还是存在更多基本问题?

我对答案的总结:这是一个Java可以允许一些"结构类型"(一种鸭子打字 - 但在编译时检查)的情况.它没有.除了一些(对我来说不清楚)性能和实现困难之外,还有一个更为基本的概念:在Java中,接口的声明(以及一般来说,所有内容)并不仅仅是结构性的(具有方法)这些签名)但语义:这些方法应该实现一些特定的行为/意图.因此,一个在结构上满足某些接口的类(即,它具有所需签名的方法)并不一定在语义上满足它(一个极端的例子:回想一下"标记接口",它甚至没有方法!).因此,Java可以断言一个类实现了一个接口,因为(并且只是因为)已经显式声明了它.其他语言(Go,Scala)有其他语言.

java duck-typing static-typing interface structural-typing

8
推荐指数
2
解决办法
748
查看次数

结构子类型反射

我们可以val s: String从函数外部获得使用反射的类型f吗?

val f = (r: {val s: String}) => {
}
Run Code Online (Sandbox Code Playgroud)

reflection scala structural-typing

8
推荐指数
1
解决办法
461
查看次数

具有自我类型的通用协议中的类方法,mypy类型检查失败

一点背景,我基本上需要定义一个int包装类型,比如说MyInt(在其他一些类中),以及另一个Interval可以接受MyInt对象以及其他类型对象的泛型类型.由于不可接受的类型Interval不属于整洁的层次结构,我认为这将是实验的完美用例Protocol,在我的情况下需要几个方法和几个@classmethods.所有方法都返回一个"自我类型",即MyInt.my_method返回一个MyInt.这是一个MCVE:

from dataclasses import dataclass
from typing import Union, ClassVar, TypeVar, Generic, Type

from typing_extensions import Protocol


_P = TypeVar('_P', bound='PType')
class PType(Protocol):
    @classmethod
    def maximum_type_value(cls: Type[_P]) -> _P:
        ...
    @classmethod
    def minimum_type_value(cls: Type[_P]) -> _P:
        ...
    def predecessor(self: _P) -> _P:
        ...
    def successor(self: _P) -> _P:
        ...

@dataclass
class MyInteger:
    value: int
    _MAX: ClassVar[int] = 42
    _MIN: ClassVar[int] = -42 …
Run Code Online (Sandbox Code Playgroud)

python class-method structural-typing python-3.x mypy

8
推荐指数
1
解决办法
608
查看次数

C#中泛型类型的命名空间范围别名

我们有一个以下示例:

public class X { }
public class Y { }
public class Z { }

public delegate IDictionary<Y, IList<Z>> Bar(IList<X> x, int i);

public interface IFoo
{
    // ...
    Bar Bar { get; }
}

public class Foo : IFoo
{
    // ...
    public Bar Bar
    {
        get
        {
            return null; //...
        }
    }
}

void Main()
{
    IFoo foo; //= ...
    IEnumerable<IList<X>> source; //= ...
    var results = source.Select(foo.Bar); // <- compile error here
}
Run Code Online (Sandbox Code Playgroud)

编译器说:

无法从用法推断出方法'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable,System.Func)'的类型参数.尝试显式指定类型参数.

这是因为它无法转换 …

c# generics alias delegates structural-typing

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

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
查看次数