【问题标题】:prevent scala function composition from inferring ? type防止scala函数组合推断?类型
【发布时间】:2013-07-12 04:38:45
【问题描述】:

我正在尝试在其类型参数中组合一些具有复合类型的函数:

trait Contains[T]
trait Sentence
trait Token
def sentenceSegmenter[T] = (c: Contains[T]) => null: Contains[T with Sentence]
def tokenizer[T <: Sentence] = (c: Contains[T]) => null: Contains[T with Token]

我的主要目标是能够用以下简单的东西来组合它们:

val pipeline = sentenceSegmenter andThen tokenizer

但是,这会产生编译错误,因为 Scala 推断 tokenizer 的类型需要是 Contains[? with Sentence] =&gt; ?

scala> val pipeline = sentenceSegmenter andThen tokenizer
<console>:12: error: polymorphic expression cannot be instantiated to expected type;
 found   : [T <: Sentence]Contains[T] => Contains[T with Token]
 required: Contains[? with Sentence] => ?

       val pipeline = sentenceSegmenter andThen tokenizer
                                                ^

我尝试了一个稍微不同的 tokenizer 定义,它更接近于 Scala 推断的类型,但我得到了类似的错误:

scala> def tokenizer[T] = (c: Contains[T with Sentence]) => null: Contains[T with Sentence with Token]
tokenizer: [T]=> Contains[T with Sentence] => Contains[T with Sentence with Token]

scala> val pipeline = sentenceSegmenter andThen tokenizer
<console>:12: error: polymorphic expression cannot be instantiated to expected type;
 found   : [T]Contains[T with Sentence] => Contains[T with Sentence with Token]
 required: Contains[? with Sentence] => ?

       val pipeline = sentenceSegmenter andThen tokenizer
                                                ^

如果我指定几乎任何类型以及sentenceSegmenter,或者如果我创建一个没有类型参数的虚假初始函数,我就可以编译:

scala> val pipeline = sentenceSegmenter[Nothing] andThen tokenizer
pipeline: Contains[Nothing] => Contains[Nothing with Sentence with Sentence with Token] = <function1>

scala> val pipeline = sentenceSegmenter[Any] andThen tokenizer
pipeline: Contains[Any] => Contains[Any with Sentence with Sentence with Token] = <function1>

scala> val begin = identity[Contains[Any]] _
begin: Contains[Any] => Contains[Any] = <function1>

scala> val pipeline = begin andThen sentenceSegmenter andThen tokenizer
pipeline: Contains[Any] => Contains[Any with Sentence with Sentence with Token] = <function1>

我不介意AnyNothing 类型被推断出来,因为我并不真正关心T 是什么。 (我主要关心with XXX 部分。)但我希望它被推断出来,而不是必须明确指定它,或者通过虚假的初始函数提供它。

【问题讨论】:

    标签: scala types function-composition


    【解决方案1】:

    您不能绑定 (val) 类型参数。您必须改用def,这样它才能在使用时绑定类型:

      def pipeline[T] = sentenceSegmenter[T] andThen tokenizer
    

    请注意,您可以使用推断类型调用管道:

    scala> new Contains[Sentence] {}
    res1: Contains[Sentence] = $anon$1@5aea1d29
    
    scala> pipeline(res1)
    res2: Contains[Sentence with Sentence with Token] = null
    

    【讨论】:

    • 但是我代码中的begin 解决方法使用val 并且一切正常,所以它不能只是valdef 的问题。此外,在您的代码中,您仍然必须明确指定 sentenceSegmenter 的类型参数,这就是我想要摆脱的......
    • 您的begin 绑定了Contains[Any] 类型,与val pipeline = sentenceSegmenter[Any] andThen tokenizer 没有什么不同。请注意,您可以在没有类型参数的情况下调用管道。
    • 我并不想在调用管道时摆脱类型参数 - 我的任何一种解决方法都不需要它。我试图在构建管道时摆脱类型参数,例如在sentenceSegmenter andThen tokenizer 行中。也许我应该澄清一下,我真的不在乎 T 得到什么解决。只要它允许sentenceSegmenter andThen tokenizer,我就可以。我稍微编辑了这个问题,希望能澄清这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 2013-05-10
    • 2013-02-19
    • 1970-01-01
    相关资源
    最近更新 更多