Skip to content

Instantly share code, notes, and snippets.

@everpeace
Last active December 13, 2015 19:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save everpeace/4964844 to your computer and use it in GitHub Desktop.
Save everpeace/4964844 to your computer and use it in GitHub Desktop.
なぜ暗黙の型変換が適用されないのかわからない><
import scala.language.higherKinds
// 代数の型クラスの階層があって
trait Algebra[E]{ def op(e1:E,e2:E):E }
trait SubAlgebra[E] extends Algebra[E]
// ある代数の型クラスのオブジェクトがあって
object ConcreteAlgebra extends SubAlgebra[Int]{
def op(e1:Int, e2:Int) = e1+e2
}
// メソッドぽくしたいからOpsトレイトを定義して
trait AlgebraOps[E]{def op(e:E):E }
// 要素と代数をpimpした値を作ってそこにOpsトレイトをくっつけて
case class Pimped[E,A[E]<:Algebra[E]](e:E, alg:A[E]) extends AlgebraOps[Pimped[E,A]]{
def op(p: Pimped[E, A]) = Pimped(alg.op(e,p.e),alg)
}
//PimpedとEの双方向の変換を用意して
//([E:Algebra]じゃないのはPimped[E,Algebra]じゃなくてPimped[E,A]になって欲しいから。)
implicit def pimp[E, A[E]<:Algebra[E]](e:E)(implicit alg: A[E]):Pimped[E,A] = Pimped(e,alg)
implicit def unpimp[E, A[E]<:Algebra[E]](p:Pimped[E,A]):E = p.e
// Intに対する代数を注入
implicit val alg = ConcreteAlgebra
// 3に対してpimpが適用されずエラーになってしまう。なぜ??
// error: value op is not a member of Int
3 op 5
// マニュアルでpimpは適用出来る。5にはちゃんとpimpが適用される。
// 結果: Pimped(8,ConcreteAlgebra$@52f61f70)
pimp(3) op 5
$ scala
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_37).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.language.higherKinds
// 代数の型クラスの階層があって
trait Algebra[E]{ def op(e1:E,e2:E):E }
trait SubAlgebra[E] extends Algebra[E]
// ある代数の型クラスのオブジェクトがあって
object ConcreteAlgebra extends SubAlgebra[Int]{
def op(e1:Int, e2:Int) = e1+e2
}
// メソッドぽくしたいからOpsトレイトを定義して
trait AlgebraOps[E]{def op(e:E):E }
case class Pimped[E,A[E]<:Algebra[E]](e:E, alg:A[E]) extends AlgebraOps[Pimped[E,A]]{
def op(p: Pimped[E, A]) = Pimped(alg.op(e,p.e),alg)
}
//PimpedとEの双方向の変換を用意して
//([E:Algebra]じゃないのはPimped[E,Algebra]じゃなくてPimped[E,A]になって欲しいから。)
implicit def pimp[E, A[E]<:Algebra[E]](e:E)(implicit alg: A[E]):Pimped[E,A] = Pimped(e,alg)
implicit def unpimp[E, A[E]<:Algebra[E]](p:Pimped[E,A]):E = p.e
// Intに対する代数を注入
implicit val alg = ConcreteAlgebra
// 3に対してpimpが適用されずエラーになってしまう。なぜ??
// error: value op is not a member of Int
3 op 5
// マニュアルでpimpは適用出来る。5にはちゃんとpimpが適用される。
// 結果: Pimped(8,ConcreteAlgebra$@52f61f70)
pimp(3) op 5
// Exiting paste mode, now interpreting.
<console>:35: error: value op is not a member of Int
3 op 5
^
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment