Skip to content

Instantly share code, notes, and snippets.

@vkostyukov
Last active August 29, 2015 14:13
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 vkostyukov/60e658da7d5c674c9d97 to your computer and use it in GitHub Desktop.
Save vkostyukov/60e658da7d5c674c9d97 to your computer and use it in GitHub Desktop.
trait R[I, O] { def apply(i: I): O } // reader
trait ToString[I] { def apply(i: I): String } // converter
case class Foo(s: String) {
def apply[I](implicit toStr: ToString[I]): R[I, String] = new R[I, String] {
def apply(i: I) = s + toStr(i)
}
def apply[I](i: I)(implicit toStr: ToString[I]): String = (apply(toStr))(i)
}
implicit val intToString = new ToString[Int] { def apply(i: Int) = i.toString }
val r: R[Int, String] = Foo("foo") // won't compile since r is `Foo`
val s1: String = r(10)
val s2: String = Foo("foo")(10)
trait R[I, O] { def apply(i: I): O } // reader
trait ToString[I] { def apply(i: I): String } // converter
class Foo[I](s: String, toString: ToString[I]) extends R[I, String] {
def apply(i: I): String = s + toString(i)
}
object Foo {
def apply[I: ToString](s: String): R[I, String] = (new Foo(s, implicitly[ToString[I]]))
def apply[I: ToString](s: String)(i: I): String = (new Foo(s, implicitly[ToString[I]]))(i)
}
implicit val intToString = new ToString[Int] { def apply(i: Int) = i.toString }
val r: R[Int, String] = Foo("foo")
val s1: String = r(10)
val s2: String = Foo("foo")(10)
println(s1)
println(s2)
/*
/Users/vkostyukov/workspace/finch-experiment.scala:17: error: ambiguous reference to overloaded definition,
both method apply in object Foo of type [I](s: String)(i: I)(implicit evidence$2: this.ToString[I])String
and method apply in object Foo of type [I](s: String)(implicit evidence$1: this.ToString[I])this.R[I,String]
match argument types (String)
val s2: String = Foo("foo")(10)
^
one error found
*/
import scala.language.implicitConversions
trait R[I, O] { def apply(i: I): O } // reader
sealed trait FooMagnet {
type In
def apply(): R[In, String]
}
implicit def fromString[I](s: String)(implicit ev: I => String) = new FooMagnet {
type In = I
def apply() = new R[In, String] {
def apply(i: In): String = ev(i) + s
}
}
object Foo {
def apply(magnet: FooMagnet): R[magnet.In, String] = magnet()
}
implicit val itos = (i: Int) => i.toString
val r = Foo("foo") // compile error:
/*
[tw-mbp-vkostyukov workspace]$ scala finch-experiment.scala
/Users/vkostyukov/workspace/finch-experiment.scala:23: error: type mismatch;
found : String("foo")
required: this.FooMagnet
val r = Foo("foo")
^
one error found
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment