I have the following:
object T {
abstract class First {
def doSomething= (s:String) => Unit
}
class Second extends First {
override def doSomething = {
(s:String) => ()
}
}
def main(args: Array[String]): Unit = {
new Second().doSomething
}
}
but this fails to compile with the error:
Error:(8, 21) type mismatch;
found : Unit
required: Unit.type
(s:String) => ()
Why isn't the override from class Second valid? How could I make it work?
The problem is that (s:String) => Unit is returning Unit.type - instead change it to (s:String) => () (or to a method if you didn't mean to be returning Function1[String, Unit] from your method.)
To put it another way:
def doSomething = (s:String) => Unit
is really:
def doSomething: (String) => Unit.type =
// A function that takes a string and returns the companion type of Unit
(s: String) => Unit
While what you probably wanted was:
def doSomething: (String) => Unit =
// A function that takes a string and returns Unit
(s: String) => ()
Or maybe:
def doSomething(s: String): Unit
// An abstract method that takes a string and returns nothing.
(s:String) => Unit returns Unit.type ie it returns the type rather than a value of that type. You want to do (s:String) => (), which will return a value, whose type is Unit.
' trait Processor0 {
def process = (x:String) => ()
}
case class Processor2() extends Processor0 {
override def process = (x:String) => println("Processor2 x :" + x)
}
case class Processor3() extends Processor0 {
override def process = (x:String) => println("Processor3 x :" + x)
}
object DemoProc2 {
def main( args : Array[String]):Unit ={
val s:String = "yes"
val myFuncs: Map[String,(String) => () ]= Map( //Error 1. '=>' expected but ']' found. 2.identifier expected but ';' found.
"string2" -> (() => ProcessorTwo().process(s)),
"string3" -> (() => ProcessorThree().process(s))
)
myFuncs.values.foreach(v => v());
}
} '
Related
I'm building a parse library that has functions with differing parameter requirements and am modeling as follows. The compiler throws the "constructor cannot be instantiated to expected type" error on the match.
Not sure why
class InstructionType[+A](name: String, params: Int) {
def paramCount = params
def executeInstruction[A](params: String*) = {
this match {
case OneParam(_, fn) => fn(Register(params(0)))
case TwoParamRegRef(_, fn) => fn(Register(params(0)), isValue(params(0)))
case TwoParamRefRef(_, fn) => fn(isValue(params(0)), isValue(params(0)))
}
}
}
case class OneParam(name: String, fn: Register => Unit) extends InstructionType[Register => Unit](name,1) {
def getInstruction = fn
}
case class TwoParamRegRef(name: String, fn: (Register, Either[Register, Int]) => Unit) extends InstructionType[(Register, Either[Register, Int]) => Unit](name,2) {
def getInstruction = fn
}
case class TwoParamRefRef(name: String, fn: (Either[Register, Int], Either[Register, Int]) => Unit) extends InstructionType[(Either[Register, Int], Either[Register, Int]) => Unit](name,2) {
def getInstruction = fn
}
I'm puzzled by the compile error for the line that defines endState. Here is the code:
import java.util.UUID
object Evaluation {
def default: Evaluation[Unit, Unit] = new Evaluation[Unit, Unit](identity)
}
case class Evaluation[From, +To](evaluate: (From) => To)
object FSMLike {
val uuidEmpty: UUID = new UUID(0L, 0L)
val endState: Evaluation[Unit, FSMLike[Nothing]] = new Evaluation(() => FSMEmpty)
lazy val stop: FSMEntry[Unit, Unit, Nothing] = FSMEntry(uuidEmpty, Evaluation.default, endState)
def apply[From1, From2, To](
action: Evaluation[From1, Unit],
nextState: Evaluation[From2, FSMLike[To]]
): (UUID, FSMLike[To]) = {
val uuid = UUID.randomUUID
uuid -> FSMEntry(uuid, action, nextState)
}
}
sealed trait FSMLike[+A]
case object FSMEmpty extends FSMLike[Nothing]
case class FSMEntry[From1, From2, +To](
id: UUID,
action: Evaluation[From1, Unit],
nextState: Evaluation[From2, FSMLike[To]]
) extends FSMLike[To] {
def transition(arg1: From1, arg2: From2): FSMLike[To] = {
action.evaluate(arg1)
nextState.evaluate(arg2)
}
override def toString: String = s"^$id^"
}
Here is the error:
Error:(14, 72) type mismatch;
found : () => FSMEmpty.type (with underlying type () => FSMEmpty.type)
required: Unit => FSMLike[Nothing]
val endState: Evaluation[Unit, FSMLike[Nothing]] = new Evaluation(() => FSMEmpty)
You are trying to pass () => FSMEmpty, a function with no arguments, where a function with one argument of type Unit is expected. Sure, when you use () as an expression, it's the only value of type Unit, but the left-hand side of => isn't an expression.
You should write _ => FSMEmpty instead. { case () => FSMEmpty } would work as well, I think, but there isn't much point to using it.
Here I create a List of objects where each element is of type (String , () => Unit)
case class FunctionDesc(label: String, fun: () => Unit)
def f() = {
println("in f")
}
val functionList = List[FunctionDesc](FunctionDesc("a1", f), FunctionDesc("a2", f))
functionList.foreach(f => f.fun())
This works fine but if I want to modify the function List to contain a parameter then have to decide what the parameter value
should be when the function is being implemented :
case class FunctionDesc2(label: String, fun: (String) => Unit)
def f2(str: String) = {
println("in f2")
}
def f3(str: String) = {
println("in f3")
}
val functionList2 = List[FunctionDesc2](FunctionDesc2("a3", f2), FunctionDesc2("a4", f3))
functionList2.foreach(f => f.fun("param value"))
Can decide what the function parameter type should before it's invoked ?
So instead of
val functionList2 = List[FunctionDesc2](FunctionDesc2("a3", f2), FunctionDesc2("a4", f3))
use something like :
val functionList2 = List[FunctionDesc2](FunctionDesc2("a3", f2("f5")), FunctionDesc2("a4", f2("f6"))
You can achieve this by making f2 and f3 return a function. Here's a simplified version:
case class FunctionDesc2(label: String, fun: (String) => Unit)
// `f` closes over `str` and returns a function from `String` to `Unit`
def f(str: String) = (s: String) => println(s"$str: $s")
val functionList = List(FunctionDesc2("a", f("foo")), FunctionDesc2("b", f("bar")))
functionList.foreach(_.fun("value"))
// foo: value
// bar: value
You can use currying:
scala> case class FunctionDesc2(label: String, fun: () => Unit)
defined class FunctionDesc2
scala> def f2(str: String)(): Unit = {
| println("in f2")
| }
f2: (str: String)()Unit
scala> def f3(str: String)(): Unit = {
| println("in f3")
| }
f3: (str: String)()Unit
scala> val functionList2 = List[FunctionDesc2](FunctionDesc2("a3", f2("f5")), FunctionDesc2("a4", f3("f6")))
functionList2: List[FunctionDesc2] = List(FunctionDesc2(a3,<function0>), FunctionDesc2(a4,<function0>))
scala> functionList2.foreach(desc => desc.fun())
in f2
in f3
I was trying to create a function pointer like:
def foo(a: String): Unit = { println(s"a = $a") }
val parameter = "some parameter"
// Here I'd want something like foo(parameter) _, but that doesn't work.
val partialFooWithParameter: () => Unit = ???
Is there something I could replace the ??? with that would work, or is this just not possible in Scala?
Update: Seems like the answer is No.
Best solutions is a function literal:
def partialFooWithParameter: () => Unit = () => foo(parameter)
Although it's still not a partially-applied function:
def bar(a: String, b: String): String = a + b
// Partially-applied.
val partial: (String => String) = bar("a", _)
// Function literal.
val literal: (String => String) = b => bar("a", b)
I think this is what you are looking for. Some of your types are incorrect.
def foo(a: String): Unit = { println(s"a = $a") }
val parameter = "some parameter"
// Here I'd want something like foo(parameter) _, but that doesn't work.
def partialFooWithParameter: () => Unit = () => foo(parameter)
I've got some code like this:
def foo (s: => Any) = println(s)
But when I want to transform this to an argument list with variable length, it won't compile anymore (tested on Scala 2.10.0-RC2):
def foo (s: => Any*) = println(s)
What must I write, that it works like this?
You have to use zero-argument functions instead. If you want, you can
implicit def byname_to_noarg[A](a: => A) = () => a
and then
def foo(s: (() => Any)*) = s.foreach(a => println(a()))
scala> foo("fish", Some(7), {println("This still happens first"); true })
This still happens first
fish
Some(7)
true
There is an issue:
https://issues.scala-lang.org/browse/SI-5787
For the accepted answer, to recover the desired behavior:
object Test {
import scala.language.implicitConversions
implicit def byname_to_noarg[A](a: => A) = () => a
implicit class CBN[A](block: => A) {
def cbn: A = block
}
//def foo(s: (() => Any)*) = s.foreach(a => println(a()))
def foo(s: (() => Any)*) = println(s(1)())
def goo(a: =>Any, b: =>Any, c: =>Any) = println(b)
def main(args: Array[String]) {
foo("fish", Some(7), {println("This still happens first"); true })
goo("fish", Some(7), {println("This used to happens first"); true })
foo("fish", Some(7), {println("This used to happens first"); true }.cbn)
}
}
Excuse the lolcats grammar.