2017-04-22 5 views
0

私はスカラのような関数の周りにドキュメントラッパーを作成しようとしています。私はこれらのうちの2つを構成するとき型が明示的に指定されていない限り、スカラ型の推論は型の境界では機能しません

import Wrapper._ 
val x : String => String = _.toLowerCase 
val y : String => String = _.toUpperCase 
val x1 = x.wrap("a function for lowercasing") 
val y1 = y.wrap("a function for uppercasing") 

println(x1("LOL")) // lol 
println(x1.doc) // a function for lowercasing 

しかし、私はタイプが推測され得るカント:

val xy = x1 compose y1 

cmd3.sc:1: inferred type arguments [Nothing,cmd3Wrapper.this.cmd1.cmd0.wrapper.WrappedFunction1[String,String]] do not conform to method compose's type parameter bounds [C,T <: cmd3Wrapper.this.cmd1.cmd0.wrapper.WrappedFunction1[String,C]] 
val xy = x1 compose y1 
      ^cmd3.sc:1: type mismatch; 
found : cmd3Wrapper.this.cmd1.cmd0.wrapper.WrappedFunction1[String,String] 
required: T 
val xy = x1 compose y1 
        ^
Compilation Failed 
ここ

trait WrappedFunction1[A, B] { 
    def f : Function1[A, B] 
    def doc: String 
    def apply(x:A):B = f(x) 
    def compose[C, T <:WrappedFunction1[B, C]](that:T):WrappedFunction1[A, C] = 
    new Wrapper[A, C](this.f andThen that.f, this.doc + " composed with " + that.doc) 
} 

class Wrapper[A, B](f1:Function1[A, B], sos:String) extends WrappedFunction1[A, B] { 
    val f = f1 
    val doc = sos 
} 

object Wrapper { 
    implicit class Wrap[A, B](f1:Function1[A, B]) { 
    def wrap(sos:String):WrappedFunction1[A, B] = new Wrapper(f1, sos) 
    } 
} 

は、私はこれを使用したい方法です

私は明示的なタイプを述べる場合は、それらが動作作曲:

val xy = x1 compose[String, WrappedFunction1[String, String]] y1 

は私が間違っているつもりだどこかにありますか? これを行うには良い方法がありますか? (私は型抜きを試みましたが、おそらく1つの型パラメータ、他の代数データ型を持つ特性のために定義されているようです)

答えて

1

問題はScalaの型推論の詳細です。最初にTを推論することはできず、次にそれからCを推論することはできません。代わりに、すぐに両方を推論する必要があります。

それはTを決定することができますが、それはNothingを割り当てられているだけで、次のステップコンパイラの通知にそれが収まらないのでCは、パラメータの型で言及されていないthat: Tから。これは、すでにWrappedFunction1[B, C]の任意のサブタイプを渡すことができますので、それで修正は、

def compose[C, T <:WrappedFunction1[B, C]](that: T with WrappedFunction1[B, C]) 

またはそれ以上に単純

def compose[C](that: WrappedFunction1[B, C]) 

をタイプを変更することです!

関連する問題