倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

「Apparent refinement of result type; are you missing an '=' sign?」って? / Scala

Scala 書いてて IntelliJ IDEA さんに警告受けたんだけど、いまいちどう修正したらいいのかわからないのでメモ。 抽象型に関係するお話。

まず、次のような Box トレイトを作る:

trait Box{
  type E
  def element:E
}

これを実装した、Int を箱に入れる IntBoxクラスはこんなの:

class IntBox(val value:Int) extends Box{
  type E = Int
  def element = value
}

// 使用例
val intBox = new IntBox(10)
println(intBox.element)  // 「10」と表示。

さて、この箱 Box をさらに入れられる部屋 Room トレイトを次のように定義しましょう:

trait Room{
  type E
  val box:Box{ type E = Room.this.E }
  val boxElement:E = box.element
}

部屋 Room の抽象型 E と、中の箱の抽象型 E と一致するように、box フィールドの型はリファインメント(?)されてます。 このトレイトの実装はこんなの:

class IntRoom(val b:IntBox) extends Room{
  type E = Int
  val box = b
}

// 使用例
val intBox = new IntBox(10)
val intRoom = new IntRoom(intBox)
println(intRoom.boxElement)  // 「10」と表示。

さて、ここで Room トレイトの定義を少し変えてみます。

trait Room{
  type E
  def box:Box{ type E = Room.this.E }
  def boxElement:E = box.element
}

フィールドをメソッドに変えました(val → def)。  で、この変更をしても IntRoom のサンプルコードは動くんですが、IntelliJ IDEA さんは「Box{ type E = Room.this.E }」の部分に「Apparent refinement of result type; are you missing an '=' sign?」という警告を出してくるんで困ってます。 何か他の宣言の仕方があるのかな? 無難に型パラメータに変えようか。

追記
下記のように新たに抽象型を定義してやると警告が出なくなりました。 ヤター!

trait Room{
  type E
  type BoxType = Box{ type E = Room.this.E }
  def box:BoxType
  def boxElement:E = box.element
}

Scala関数型デザイン&プログラミング ―Scalazコントリビューターによる関数型徹底ガイド (impress top gear)

Scala関数型デザイン&プログラミング ―Scalazコントリビューターによる関数型徹底ガイド (impress top gear)

Scalaスケーラブルプログラミング第2版

Scalaスケーラブルプログラミング第2版

  • 作者: Martin Odersky,Lex Spoon,Bill Venners,羽生田栄一,水島宏太,長尾高弘
  • 出版社/メーカー: インプレスジャパン
  • 発売日: 2011/09/27
  • メディア: 単行本(ソフトカバー)
  • 購入: 12人 クリック: 235回
  • この商品を含むブログ (45件) を見る