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
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());
}
} '
My aim: To minimize lines of code.
Have a few function like f1, f2 ...
f1(A: String)
f2(A: String, B: Long, C: User)
Want to process it with high order function approach.
def processf1(request: Request[AnyContent], f: (String) => String)
def processf2(request: Request[AnyContent], f: (String, Long, User) => String) = {...}
Can I create ONE common process function for f1, f2 ?
Any ideas ?
Thanks.
You could parametrize processf types:
def processf[S,T](request: Request[S], f: T => String) = ...
Examples of use:
processf(new Request[Int], (x: String) => x)
processf(new Request[Int], (x: (String, Long, User)) => x._1)
Thanks for the answer, but not so clear for me, could please clarify
for example 3 function which have duplicate like RequestUtil.getRequestParams
private def regUser(request: Request[AnyContent], f: (String) => String): String = {
RequestUtil.getRequestParams(request, APPConst.USER) match {
case Some(map) => f(map(APPConst.USER))
case None => JsonUtil.toJson(APPConst.ERROR -> APPConst.POST_PARAMS_EMPTY_MISMATCH)
}
}
private def regDog(request: Request[AnyContent], f: (Dog, Enum, String, String) => String): String = {
RequestUtil.getRequestParams(request, APPConst.Dog) match {
case Some(m) => process(m, f)
case None => JsonUtil.toJson(APPConst.ERROR -> APPConst.POST_PARAMS_EMPTY_MISMATCH)
}
}
private def regCat[T](request: Request[AnyContent], f: (Cat, Enum) => String): String = {
RequestUtil.getRequestParams(request, APPConst.CAT) match {
case Some(map) => process(map, f)
case None => JsonUtil.toJson(APPConst.ERROR -> APPConst.POST_PARAMS_EMPTY_MISMATCH)
}
}
and executions
def regUser = Action { request => Ok(views.html.index(regUserProcess(request, UserService.regUser)))}
def regDog = Action { request => Ok(views.html.index(regCurrProcess(request, UserService.regDog)))}
def regCat = Action { request => Ok(views.html.index(mainProcess(request, UserService.regCat)))}
As you can see 3 different functions with different count parameters UserService.regUser, UserService.regDog, UserService.regCat functions
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 want to convert a partial function into a "safe" partial function, i.e. PartialFunction[T,R] into a PartialFunction[T,Try[R]], is there any better way than the following implementation?
def safe[T,R](pf:PartialFunction[T,R]):PartialFunction[T,Try[R]]=new PartialFunction[T, Try[R]]{
def isDefinedAt(t:T) = pf.isDefinedAt(t)
def apply(t:T) = Try(pf.apply(t))
}
You can define safe using a for expression:
def safe[T,R](pf:PartialFunction[T,R]) = PartialFunction {
(t:T) => for(a <- Try(pf(t))) yield a
}
Or using an implicit class:
object SafeImplicit {
implicit class Safe[T,R](pf: PartialFunction[T,R]){
def safe(t: =>T) = for(a<-Try(pf(t))) yield a
}
}
import SafeImplicit.Safe
def f: PartialFunction[Int, String] = {case 1 => "one"}
def g: PartialFunction[Int, String] = {case 1 => "a".toInt;"one"}
f.safe(1) // Success(one)
f.safe(2) // Failure(scala.MatchError: 2 ...)
f.safe("a".toInt) // Failure(java.lang.NumberFormatException ...)
g.safe(1) // Failure(java.lang.NumberFormatException ...)
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.