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)
Related
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());
}
} '
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 am trying to translate examples from this article to Scala.
So I defined a monadic class Parser with success as return function.
class Parser[A](val run: String => List[(A, String)]) {
def apply(s: String) = run(s)
def flatMap[B](f: A => Parser[B]): Parser[B] = {
val runB = {s: String => for((r, rest) <- run(s); rb <- f(r)(rest)) yield rb}
new Parser(runB)
}
}
def success[A](a:A):Parser[A] = {
val run = {s:String => List((a, s))}
new Parser(run)
}
I defined also a new parser item to return the 1st character of the input.
def item(): Parser[Char] = {
val run = {s: String => if (s.isEmpty) Nil else List((s.head, s.tail))}
new Parser(run)
}
Now I am defining a new parser item12: Parser[(Char, Char)] to return a pair of 1st and 2nd characters
def item12():Parser[(Char, Char)] =
item().flatMap(a => (item().flatMap(b => success(a, b))))
I would like to write it with for-comprehension instead of nested flatMap calls. I understand that I need to define a map method for the Parser. How would you do that ?
I understand that I need to define a map method for the Parser. How would you do that ?
def map[B](f: A => B): Parser[B] = {
val runB = {s: String => ???} // you need to call run and f here
new Parser(runB)
}
I am leaving the body of runB in case you want to do it yourself.
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.
just a quick question I seem to be unable to find an answer to.
I have a method definition in Scala that looks like this:
def execute(goals: List[String],
profiles: List[String] = List(),
loggingCallback: (String) => Unit = { _ => }): Result = {
// method body
loggingCallback("a message")
}
I would like to know whether there is a better way to specify a default empty closure. The question is not about how to implement logging, this is just an example.
Your solution is fine. You could introduce a type alias for Function1[X, Unit]; use () as per Kevin's answer, and drop unnecessary parens.
scala> type Effect[-A] = (A => Unit)
defined type alias Effect
scala> def foo(f: Effect[String] = _ => ()) = ()
foo: (f: (String) => Unit)Unit
You could also define a noop function:
scala> val noop = (a: Any) => ()
noop: (Any) => Unit = <function1>
scala> def foo(f: Effect[String] = noop) = ()
The value () is an instance of unit, so this should do the trick:
def execute(
goals: List[String],
profiles: List[String] = Nil,
loggingCallback: (String) => Unit = { _ => () }): Result =
{
// method body
loggingCallback("a message")
// do something returning a Result
}
update
If something is optional, then it often makes more sense to state so explicitly, this also results in better self-documenting code:
def execute(
goals: List[String],
profiles: List[String] = Nil,
loggingCallback: Option[(String) => Unit] = None): Result =
{
// method body
loggingCallback forEach { _.apply("a message") }
// do something returning a Result
}
update 2
DSL-esque situations like this are also one of the very few situations where I'll condone the use of null in Scala:
def execute(
goals: List[String],
profiles: List[String] = Nil,
loggingCallback: (String) => Unit = null
): Result = {
// method body
val log = Option(loggingCallback) getOrElse {_ => ()}
log("a message")
// do something returning a Result
}
Note the Option(loggingCallback) to immediately convert the nullable loggingCallback into a nice type-safe Option, then getOrElse to provide a fallback alternative.