1. ホーム
  2. スカラ

[解決済み】Scala 2.8における<:<、<%<、=:=の意味と、それらのドキュメントはどこにあるのか?

2022-04-18 01:21:09

質問

API ドキュメントにある プレデフ 汎用関数型(From)=> Toのサブクラスである、としか書かれていないのですが。 えーと、なんだっけ? どこかにドキュメントがあるのかもしれませんが、検索エンジンは "<:<" のような "name" をうまく扱わないので、見つけられずにいます。

続いての質問:これらのファンキーな記号/クラスはいつ使えばいいのでしょうか?

どのように解決するのですか?

これらは 一般化された型制約 . これによって,型パラメタ化されたクラスやトレイトの中で,次のようなことが可能になります. さらに制約をかける の型パラメーターの1つです。以下はその例である。

case class Foo[A](a:A) { // 'A' can be substituted with any type
    // getStringLength can only be used if this is a Foo[String]
    def getStringLength(implicit evidence: A =:= String) = a.length
}

暗黙の引数 evidence はコンパイラによって提供されます。 AString . と考えることができます。 証明 その AString -議論そのものは重要ではなく、それが存在することを知ることだけが重要なのです。 [編集:まあ、技術的には重要なのですが。 A から String を呼び出すことができるものです。 a.length で、コンパイラから怒鳴られることはありません] 。

これで、こんな風に使えるようになりました。

scala> Foo("blah").getStringLength
res6: Int = 4

しかし、これを Foo 以外のものを含む String :

scala> Foo(123).getStringLength
<console>:9: error: could not find implicit value for parameter evidence: =:=[Int,String]

このエラーは "could not find evidence that Int == String" と読めますが、その通りです! getStringLength は堂々としている さらなる制限 のタイプについて A 何よりも Foo を呼び出すことができます。 getStringLength の上で Foo[String] . この制約がコンパイル時に適用されるのは素晴らしいことです。

<:<<%< の動作は似ていますが、若干の違いがあります。

  • A =:= B は、Aは正確にBでなければならないことを意味する
  • A <:< B は、AはBのサブタイプでなければならないことを意味します(類似のものとして シンプル 型制約 <: )
  • A <%< B は、Aは必ず ビューアブル をBとして、おそらく暗黙の変換によって(単純な型制約に類似した <% )

このスニペット は、この種のことが以前はどのように達成されていたか、そして一般化された型制約が現在どのようにそれを容易にしているかについて、良い説明をしています。

追記

確かに、私が挙げた例はかなり作為的で、明らかに有用とは言えません。しかし、この例を使って、次のようなものを定義することを想像してみてください。 List.sumInts メソッドは、整数のリストを足し算するものです。このメソッドは、古くなった List のみならず List[Int] . しかし List 文字列、フォース、バー、その他のリストが必要だからです。そこで、一般化された型制約を sumInts を確保することができます。 そのメソッドだけ に対してのみ使用できるという制約が追加されています。 List[Int] . 要するに、ある種のリストに対して特殊なコードを書いているわけです。