Scala 2.10:
class A(val x:Int=0) {
}
object A {
def apply(x:Int): A = new A(x) // works
def apply(): A = new A() // fails to compile
}
val b = A(123) // :-)
val a = A() // >-(
Solution?
Even though your code should work (I suspect some implicit argument being at work here)
you can simplify it by doing
object A {
def apply(x: Int=0): A = New A(x)
}
while being shorter there's the drawback of being less DRY
Related
I want to bind a check method to the Test in such a way that the implementation does not contain an argument (look at the last line). It is necessary to use type classes here, but I'm new in Scala, so I have problems.
Object Checker is my attempts to solve the problem. Perhaps it is enough to make changes to it...
trait Test[+T] extends Iterable[T]
class TestIterable[+T](iterable: Iterable[T]) extends Test[T] {
override def iterator: Iterator[T] = iterable.iterator
}
object Test {
def apply[T](iterable: Iterable[T]): Test[T] = new TestIterable[T](iterable)
}
trait Check[M] {
def check(m: M): M
}
object Checker {
def apply[M](implicit instance: Check[M]): Check[M] = instance
implicit def checkSyntax[M: Check](m: M): CheckOps[M] = new CheckOps[M](m)
private implicit def test[T](m: Test[T]) : Check[Test[T]] = {
new Check[Test[T]] {
override def check(m: Test[T]) = m
}
}
final class CheckOps[M: Check](m: M) {
def x2: M = Checker[M].check(m)
}
}
import Checker._
val test123 = Test(Seq(1, 2, 3))
Test(test123).check
I should create class Example[T] with 2 different implementations:
If T can be converted to Numeric
Another case
I tried to do this with implicit conversion
class ExampleImplicits{
implicit def convert[T](example: Example[T]): ExampleSecond[T] = new ExampleSecond[T]()
}
class Example[T:Numeric]...
class ExampleSecond[T]...
I thought that if compiler will not find implicit conversion in scala.Numeric.Implicit for T, then he will raise my implicit conversion.
But as I tested code, this works not like this. How can I do this specialization?
UPDATE
What I want to get:
val x = new Example[Int]()
x.methodThatHaveOnlyNumerics()
x.methodThatHaveAllImplementations()
val y = new Example[String]()
y.methodThatHaveAllImplementations()
Now I can't compile my code.
Just create an implicit class that provides the additional methods in the case that the type parameter is Numeric:
class Example[X] {
def methodThatHaveAllImplementations(): Unit = println("all")
}
implicit class ExampleNumOps[N: Numeric](ex: Example[N]) {
def methodThatHaveOnlyNumerics(): Unit = println("num")
}
val x = new Example[Int]()
x.methodThatHaveOnlyNumerics()
x.methodThatHaveAllImplementations()
val y = new Example[String]()
y.methodThatHaveAllImplementations()
Output:
num
all
all
I tested this code. And it seems code working as expected. Here object ob returns ExampleSecond[Int]. I tested with below code.
I hope this is what you expecting.
object HelloWorld {
def main(args: Array[String]): Unit = {
val ex = new Example[Int]
val x = new ExampleImplicits
val ob = x.convert(ex) // passing Example[Int] object to convert
println(ob.isInstanceOf[ExampleSecond[Int]]) // returns true because it is of ExaampleSecond[Int] object.
}
}
class ExampleImplicits {
implicit def convert[T](example: Example[T]): ExampleSecond[T] = new ExampleSecond[T]()
}
class Example[T: Numeric] {
println("ex")
}
class ExampleSecond[T] {
println("ex2")
}
Output :
ex
ex2
true
An alternative to Andrey's answer:
class Example[T] {
def methodThatHaveOnlyNumerics()(implicit num: Numeric[T]) = ...
def methodThatHaveAllImplementations() = ...
}
How can i solve this simple problem. Class Conversion has a typed method from wich takes two type parameters A and B and returns a B from an A. I have defined some implicits in the companion object to provide default beahviour.
My Problem is when i try to forward the call to the Conversion class within another typed method which has the same signature it does not work. Here in my example i try to forward the call from function myFun to my Conversion class.
I got following error
not enough arguments for method from: (implicit f: A => B)
I am wondering why this makes any problems. Can someone explain me why and how to overcome this problem ?
Here is the code
object MyConversions {
implicit val IntToStr = (f:Int) => f.toString()
implicit val DoubleToStr = (f:Double) => f.toString()
implicit val BooleanToStr = (f:Boolean) => f.toString()
}
class Conversions{
def from[A,B](a:A)(implicit f:(A) => B) = {
f(a)
}
}
import MyConversions._;
def myFun[A,B](a:A){
// Error
new Conversions().from[A, B](a)
}
// Working
println( new Conversions().from[Int, String](3) )
The problem is that the Scala compiler cannot find an implicit value for the parameter f: (A) => B in the scope of myFun. What you have to do is to tell the compiler that myFun can only be called, when there is such a value available.
The following code should do the trick
object App {
trait Convertible[A, B] {
def convert(a: A): B
}
object Convertible {
implicit val int2String = new Convertible[Int, String] {
override def convert(a: Int): String = a.toString
}
implicit val float2String = new Convertible[Float, String] {
override def convert(a: Float): String = a.toString
}
}
def myFun[A ,B](a:A)(implicit converter: Convertible[A, B]): B = {
converter.convert(a)
}
def main(args: Array[String]): Unit = {
println(myFun(3))
}
}
In short, I want to declare a trait like this:
trait Test {
def test(amount: Int): A[Int] // where A must be a Monad
}
so that I can use it without knowing what monad that A is, like:
class Usecase {
def someFun(t: Test) = for { i <- t.test(3) } yield i+1
}
more details...
essentially, I want to do something like this:
class MonadResultA extends SomeUnknownType {
// the base function
def test(s: String): Option[Int] = Some(3)
}
class MonadResultB(a: MonadResultA) extends SomeUnknownType {
// added a layer of Writer on top of base function
def test(s: String): WriterT[Option, String, Int] = WriterT.put(a.test(s))("the log")
}
class Process {
def work(x: SomeUnknownType) {
for {
i <- x.test("key")
} yield i+1
}
}
I wanted to be able to pass any instances of MonadResultA or MonadResultB without making any changes to the function work.
The missing piece is that SomeUnknowType, which I guess should have a test like below to make the work function compiles.
trait SomeUnknowType {
def test(s: String): T[Int] // where T must be some Monad
}
As I've said, I'm still learning this monad thing... if you find my code is not the right way to do it, you're more than welcomed to point it out~
thanks a lot~~
Assuming you have a type class called Monad you can just write
def test[A:Monad](amount: Int): A[Int]
The compiler will require that there is an implicit of type Monad[A] in scope when test is called.
EDIT:
I'm still not sure what you're looking for, but you could package up a monad value with its corresponding type class in a trait like this:
//trait that holds value and monad
trait ValueWithMonad[E] {
type A[+E]
type M <: Monad[A]
val v:A[E]
val m:M
}
object M {
//example implementation of test method
def test(amount:Int):ValueWithMonad[Int] = new ValueWithMonad[Int] {
type A[+E] = Option[E]
type M = Monad[Option]
override val v = Option(amount)
override val m = OptionMonad
}
//test can now be used like this
def t {
val vwm = test(1)
vwm.m.bind(vwm.v, (x:Int) => {
println(x)
vwm.m.ret(x)
})
}
}
trait Monad[A[_]] {
def bind[E,E2](m:A[E], f:E=>A[E2]):A[E2]
def ret[E](e:E):A[E]
}
object OptionMonad extends Monad[Option] {
override def bind[E,E2](m:Option[E], f:E=>Option[E2]) = m.flatMap(f)
override def ret[E](e:E) = Some(e)
}
I've found extremely weird behaviour (scala 2.9.1 ) using and defining implicit values, and wondering if anyone can explain it, or if it's a scala bug?
I've created a self contained example:
object AnnoyingObjectForNoPurpose {
trait Printer[T] {
def doPrint(v: T): Unit
}
def print[T : Printer](v: T) = implicitly[Printer[T]].doPrint(v)
trait DelayedRunner extends DelayedInit {
def delayedInit(x: => Unit){ x }
}
// this works, as it should
object Normal extends DelayedRunner {
implicit val imp = new Printer[Int] {
def doPrint(v: Int) = println(v + " should work")
}
print(343)
}
// this compiles, but it shouldn't
// and won't run, cause the implicit is still null
object FalsePositive extends DelayedRunner {
print(123)
implicit val imp = new Printer[Int] {
def doPrint(v: Int) = println(v + " should not compile")
}
}
def main(args: Array[String]) {
implicit val imp = new Printer[Int] {
def doPrint(v: Int) = println(v + " should work")
}
print(44)
// print(33.0) // correctly doesn't work
Normal // force it to run
FalsePositive // force this to run too
}
}
Suppose you changed your definition of delayInit to be a no-op, i.e.
def delayedInit(x: => Unit) { }
Then in your main method do something like
println("FP.imp: " + FalsePositive.imp)
As expected that will print FP.imp: null, but the real point of the exercise is to illustrate that the block that defines the body of FalsePositive is acting like a regular class body, not a function body. It's defining public members when it sees val, not local variables.
If you added a method to AnnoyingObjectForNoPurpose like the following, it wouldn't compile because print's implicit requirement isn't satisfied.
def fails {
print(321)
implicit val cantSeeIt = new Printer[Int] {
def doPrint(v: Int) = println(v + " doesn't compile")
}
}
However if you defined a class along the same principle, it would compile, but fail at runtime when initialized, just like your FalsePositive example.
class Fine {
print(321)
implicit val willBeNull = new Printer[Int] {
def doPrint(v: Int) = println(v + " compiles, but fails")
}
}
To be clear, the compile behavior of Fine has nothing to do with the presence of the implicit. Class/object initializers are very happy to compile with val initializers which reference undefined vals.
object Boring {
val b = a
val a = 1
println("a=%s b=%s".format(a, b))
}
Boring compiles just fine and when it is referenced, it prints a=1 b=0
It seems like your question boils down to "Should the body of a class/object deriving from DelayedInit be compiled as if it's a class body or a function block?"
It looks like Odersky picked the former, but you're hoping for the latter.
That's the same bug as if I write this:
object Foo {
println(x)
val x = 5
}
It ain't a bug. Your constructor flows down the object body and happens in order. DelayedInit isn't the cause. This is why you need to be careful when using val/vars and ensure they init first. This is also why people use lazy val's to resolve initialization order issues.