【问题标题】:Sorbet generics question - method with type variable in parameter position冰糕泛型问题 - 在参数位置具有类型变量的方法
【发布时间】:2021-10-17 01:45:58
【问题描述】:

我正在尝试让这个 Sorbet 代码工作(here 在 Sorbet 操场上):

# typed: true

extend T::Sig
extend T::Generic

class Foo
  extend T::Sig
  extend T::Generic

  TypeParam = type_member
end

class FooA < Foo
  TypeParam = type_member(fixed: Integer)
end

sig {type_parameters(:MyParam)
      .params(foo: Foo[T.type_parameter(:MyParam)]).void}
def blah(foo)
end

my_foo = FooA.new
blah(T.cast(my_foo, Foo[Integer]))

但是,我遇到了类型错误:

editor.rb:23: Expected Foo[T.type_parameter(:MyParam)] but found Foo[Integer] for argument foo https://srb.help/7002
    23 |blah(T.cast(my_foo, Foo[Integer]))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  Expected Foo[T.type_parameter(:MyParam)] for argument foo of method Object#blah:
    editor.rb:18:
    18 |      .params(foo: Foo[T.type_parameter(:MyParam)]).void}
                      ^^^
  Got Foo[Integer] originating from:
    editor.rb:23:
    23 |blah(T.cast(my_foo, Foo[Integer]))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Errors: 1

我不确定如何对blah 方法进行单态化,以便它可以接受Foo[Integer] 类型的参数。 Sorbet 目前是否支持此用例?

【问题讨论】:

    标签: ruby sorbet


    【解决方案1】:

    如果我理解您正在尝试正确执行的操作,并且您希望 blah只需采用 Foo[Integer] 类型的参数,您可以这样做:

    sig {params(foo: Foo[Integer]).void}
    def blah(foo)
    end
    

    你可以看到一个完整的例子(类型不符合接口here):

    class Foo
      extend T::Sig
      extend T::Generic
    
      TypeParam = type_member
    end
    
    class FooA < Foo
      TypeParam = type_member(fixed: Integer)
    end
    
    class FooB < Foo
      TypeParam = type_member(fixed: String)
    end
    
    sig {params(foo: Foo[Integer]).void}
    def blah(foo)
    end
    
    my_foo = FooA.new
    blah(my_foo)
    
    my_bad_foo = FooB.new
    blah(my_bad_foo)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多