2017-11-14 11 views
0

私はスカラの初心者です...無知を仮定します。そうは高次の型を暗黙的に変換します

Iは<の定義を見れば:<

sealed abstract class <:<[-From, +To] extends (From => To) implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x}

、これはタイプAはB.

<のサブタイプであることの証拠を定義するために使用される:B

...しかし、もし私がその証拠を持っていたいなら、 B [T]

:T. A [T] < FORALL

OK ....ので、私は同じレシピ

abstract class Foo[-A[_],+B[_]] { def apply[C](x : A[C]) : B[C] } 

implicit def conforms[A[_]] : Foo[A,A] = new Foo[A,A] { def apply[C](x : A[C]) : A[C] = x } 

に従うことをしようと、私は手動で変換を適用し、この制約を使用することができますが、私は暗黙のうちにそれを「適用」するようにコンパイラを取得することはできません。 (A => Bを拡張しないため)

などです。

abstract class FooInt[-A[_],+B[_]] extends (A[Int] => B[Int]) 

implicit def conformsInt[A[Int]] : FooInt[A,A] = new FooInt[A,A] { def apply(x : A[Int]) : A[Int] = x } 

その後、コンパイラが自動的にタイプA [INT]の値に変換を適用します

私はちょうど[T]

の考えにこれを一般化したい

+0

をあなたが求めているものは不明です。 'Foo'のユースケースを追加して、どこに行きたいのかを理解する必要があります。 F#はHM型であるのに対し、Scalaは名目上型付けされていることに注意してください。混乱はそこから起こると思う。 –

+0

hmmm ...私は考えてみましょう実際に完全な例を与える問題はすべてそれが泥の中に隠れているということです – user2088029

+0

暗黙の変換は私たちが "A => B"を実装すると仮定しているということです – user2088029

答えて

0

sealed abstract class <:< - これは「新しい証拠」を構築できないことを示しています。既存の2つのタイプが既存の証拠を満たしていることをコンパイラーに頼らざるを得ません。これはすでにすべてのタイプで動作するはずです。そうでない場合は、間違っていることを証明しようとします。

あなたは、そのことを証明したいと述べています。A[T] <: B[T] forAll { type T }。これは、AとBの型パラメータの分散に依存します。そのパラメータを無視したい場合は、証拠A[_] <:< B[_]のみを要求することができます。例えば。

trait Animal; trait Cat extends Animal 

trait Foo[A] 
trait Bar[A] extends Foo[A] 

implicitly[Bar[Cat] <:< Foo[Cat]]  // ok, A is fixed 
implicitly[Bar[Cat] <:< Foo[Animal]] // not possible 
implicitly[Bar[Animal] <:< Foo[Cat]]  // not possible 
implicitly[Bar[_]  <:< Foo[_]]  // ok, we forget about A 

あなたが分散していた場合、あなたは保存できます。

trait Breeds[+A] // covariant, can "produce" A 
trait Feeds [-A] // contravariant, can "consume" A 
class Baz[A] extends Breeds[A] with Feeds[A] 

implicitly[Baz[Cat] <:< Feeds[Animal]] // nope 
implicitly[Baz[Animal] <:< Feeds[Cat]]  // ok 
implicitly[Baz[Cat] <:< Breeds[Animal]] // ok 
implicitly[Baz[Animal] <:< Breeds[Cat]] // nope 
+0

はこの有効なスカラですか? "A [T] <:B [T] forAll {type T}" – user2088029

+0

@ user2088029いいえ、普遍的な定量化された 'T'について話す方法です。 –

+0

@ user2088029いいえ、あなたがそのようなタイプを定義できるということを意味するならば。しかし、型パラメータTが["existential"](https://www.cakesolutions.net/teamblogs/existential-types-in-scala)であるという点で、A [_] <:B [_] ' )。 –

関連する問題