My assignment is to write a custom repeat control structure that can be used like this:
var i = 0
repeat {
i = i + 1
}(i > 5)
I currently have the following code for that:
def repeat(f: => Unit): ((=> Boolean) => Unit) = {
(x) => {
while (x) f
}
}
When running this, it seems f (i = i + 1) is never executed.
I have to be honest, I'm not entirely sure what the current type of x is. It's clearly not correct, but I don't have enough knowledge to know where to go from here.
I used to have this:
def repeat(f: => Unit): ((=> Boolean) => Void) = {
(x: (=> Boolean)) => {
while (x) f
}
}
Although this is apparently incorrect Scala, I think it demonstrates my intent better.
I'm sorry if my question is a bit broad/demonstrates effortlessness, but the concept of by-name parameters is very new to me and not explained in my book (Programming in Scala) beyond the basics.
You should also be aware that Scala supports multiple parameter lists. So you could
def compare(a: Int, b: Int)(p: (Int,Int) => Boolean) = p(a,b)
and then write
compare(5,2)(_ > _)
This type of strategy will simplify your logic.
Also, you have your comparison backwards. i starts out at 0 and your loop condition is i > 5, which it is not.
A few extra notes: => X means "compute an X each time one is needed", so ((=> Boolean) => Unit) takes something that will compute a Boolean as needed (and i > 5 can do that, if the check is performed each time, which it will be). (=> Boolean) => Unit means a function that takes as input something that produces Booleans and gives no output. (Well, strictly speaking, Unit type is an output, namely (), which is done for consistency. But it serves the same role as void.)
Related
I am working on the Coursera's Scala tutorials. One of the exercises asks to implement a map function to sets type that are defined as follows:
type Set = Int => Boolean. There was a stub for the function:
/**
* Returns a set transformed by applying `f` to each element of `s`.
*/
def map(s: Set, f: Int => Int): Set = ???
I thought that one can check if an element is in s, by doing the following:
(x: Int) => s(x). Which I am thinking should be equivalent to whatever the definition of a set is. Thus, if we want to apply transformation on the set, we can do:
(x: Int) => s(f(x)). And so the definition of function is:
def map(s: Set, f: Int => Int): Set = s(f(x)). But this gives me some weird set if I try it on:
def map(s: Set, f: Int => Int): Set = (x: Int) => s(f(x))
def toStringH(s: Set): String = {
val xs = for (i <- -bound to bound if contains(s, i)) yield i
xs.mkString("{", ",", "}")
}
def printSet(s: Set) { println(toStringH(s)) }
val squaredSet = map((x: Int) => (x> -3 & x<3), (x:Int) => (x+1))
printSet(squaredSet)
So I am wondering where I went wrong. Thanks.
I expect that you mean the progfun1 course by Martin Odersky and its Week 2 task. I believe that generally there is no solution for this problem (it requires finding a reverse function for a given function which I doubt is really possible) and the course authors know about that. Thus they added an additional restriction that you probably missed (I highlighted the important part):
Note that there is no direct way to find which elements are in a set. contains only allows to know whether a given element is included. Thus, if we wish to do something to all elements of a set, then we have to iterate over all integers, testing each time whether it is included in the set, and if so, to do something with it. Here, we consider that an integer x has the property -1000 <= x <= 1000 in order to limit the search space.
Although it is a comment for the forall task it is in the same section and just a few paragraphs above the map task.
I have superficially read a couple of blog articles/Wikipedia about continuation-passing style. My high-level goal is to find a systematic technique to make any recursive function (or, if there are restrictions, being aware of them) tail-recursive. However, I have trouble articulating my thoughts and I'm not sure if what my attempts of it make any sense.
For the purpose of the example, I'll propose a simple problem. The goal is, given a sorted list of unique characters, to output all possible words made out of these characters in alphabetical order. For example, sol("op".toList, 3) should return ooo,oop,opo,opp,poo,pop,ppo,ppp.
My recursive solution is the following:
def sol(chars: List[Char], n: Int) = {
def recSol(n: Int): List[List[Char]] = (chars, n) match {
case (_ , 0) => List(Nil)
case (Nil, _) => Nil
case (_ , _) =>
val tail = recSol(n - 1)
chars.map(ch => tail.map(ch :: _)).fold(Nil)(_ ::: _)
}
recSol(n).map(_.mkString).mkString(",")
}
I did try to rewrite this by adding a function as a parameter but I did not manage to make something I was convinced to be tail-recursive. I prefer not including my attempt(s) in the question as I'm ashamed of their naiveness, so please excuse me for this.
Therefore the question is basically: how would the function above be written in CPS ?
Try that:
import scala.annotation.tailrec
def sol(chars: List[Char], n: Int) = {
#tailrec
def recSol(n: Int)(cont: (List[List[Char]]) => List[List[Char]]): List[List[Char]] = (chars, n) match {
case (_ , 0) => cont(List(Nil))
case (Nil, _) => cont(Nil)
case (_ , _) =>
recSol(n-1){ tail =>
cont(chars.map(ch => tail.map(ch :: _)).fold(Nil)(_ ::: _))
}
}
recSol(n)(identity).map(_.mkString).mkString(",")
}
The first order of business in performing the CPS transform is deciding on a representation for continuations. We can think of continuations as a suspended computation with a "hole". When the hole is filled in with a value, the remainder of the computation can be computed. So functions are a natural choice for representing continuations, at least for toy examples:
type Cont[Hole,Result] = Hole => Result
Here Hole represents the type of the hole that needs to be filled in, and Result represents the type of value the computation ultimately computes.
Now that we have a way to represent continuations, we can worry about the CPS transform itself. Basically, this involves the following steps:
The transformation is applied recursively to an expression, stopping at "trivial" expressions / function calls. In this context, "trivial" includes functions defined by Scala (since they are not CPS-transformed, and thus do not have a continuation parameter).
We need to add a parameter of type Cont[Return,Result] to each function, where Return is the return type of the untransformed function and Result is the type of the ultimate result of the computation as a whole. This new parameter represents the current continuation. The return type for the transformed function is also changed to Result.
Every function call needs to be transformed to accommodate the new continuation parameter. Everything after the call needs to be put into a continuation function, which is then added to the parameter list.
For example, a function:
def f(x : Int) : Int = x + 1
becomes:
def fCps[Result](x : Int)(k : Cont[Int,Result]) : Result = k(x + 1)
and
def g(x : Int) : Int = 2 * f(x)
becomes:
def gCps[Result](x : Int)(k : Cont[Int,Result]) : Result = {
fCps(x)(y => k(2 * y))
}
Now gCps(5) returns (via currying) a function that represents a partial computation. We can extract the value from this partial computation and use it by supplying a continuation function. For example, we can use the identity function to extract the value unchanged:
gCps(5)(x => x)
// 12
Or, we can print it by using println instead:
gCps(5)(println)
// prints 12
Applying this to your code, we obtain:
def solCps[Result](chars : List[Char], n : Int)(k : Cont[String, Result]) : Result = {
#scala.annotation.tailrec
def recSol[Result](n : Int)(k : Cont[List[List[Char]], Result]) : Result = (chars, n) match {
case (_ , 0) => k(List(Nil))
case (Nil, _) => k(Nil)
case (_ , _) =>
recSol(n - 1)(tail =>
k(chars.map(ch => tail.map(ch :: _)).fold(Nil)(_ ::: _)))
}
recSol(n)(result =>
k(result.map(_.mkString).mkString(",")))
}
As you can see, although recSol is now tail-recursive, it comes with the cost of building a more complex continuation at each iteration. So all we've really done is trade space on the JVM's control stack for space on the heap -- the CPS transform does not magically reduce the space complexity of an algorithm.
Also, recSol is only tail-recursive because the recursive call to recSol happens to be the first (non-trivial) expression recSol performs. In general, though, recursive calls would be take place inside a continuation. In the case where there is one recursive call, we can work around that by transforming only calls to the recursive function to CPS. Even so, in general, we would still just be trading stack space for heap space.
This is a follow-up to my previous question
Suppose I have two validating functions that return either the input if it is valid or the error messages if it is not.
type Status[A] = ValidationNel[String, A]
val isPositive: Int => Status[Int] =
x => if (x > 0) x.success else s"$x not positive".failureNel
val isEven: Int => Status[Int] =
x => if (x % 2 == 0) x.success else s"$x not even".failureNel
Suppose also that I need to validate an instance of case class X:
case class X(x1: Int, // should be positive
x2: Int) // should be even
More specifically I need a function checkX: X => Status[X]. Moreover, I'd like to write checkX as a composition of isPositive and isEven.
val checkX: X => Status[X] =
({x => isPositive(x.x1)} |#| {x => isEven(x.x2)}) ((X.apply _).lift[Status])
Does it make sense ?
How would you write checkX as a composition of isPositive and isEven?
There are lots of ways to write this, but I like the following:
val checkX: X => Status[X] = x => isPositive(x.x1).tuple(isEven(x.x2)).as(x)
Or:
val checkX: X => Status[X] =
x => isPositive(x.x1) *> isEven(x.x2) *> x.point[Status]
The key point is that you want to run the two validations only for their "effects" and then return the original value in the new context. This is a perfectly legitimate applicative operation, as your own implementation shows. There are just some slightly nicer ways to write it.
It doesn't make sense, because the two functions can't really be composed. You'd (presumably) like to check whether x is positive and whether x is even - but in the case where it is both negative and odd, you'd like to receive both errors. But that can't ever happen as a composition of those two functions - once you apply either of the failing cases, you don't have an x any more to pass to the second function.
In my experience Validation is almost never the correct type to use, for this very reason.
If you want "fail-fast" behaviour where the result is either success or the first error, you should use \/ (i.e. type Status[A] = String \/ A in this case). If you want "accumulate all the error messages alongside the value" behaviour, you want Writer, i.e. type Status[A] = Writer[Vector[String], A]. Both of these types allow easy composition (because they have monad instances available) using e.g. Kleisli: Kleisli(isPositive) >==> isEven would work for either of these definitions of Status (but not for yours).
In Scala, I have progressively lost my Java/C habit of thinking in a control-flow oriented way, and got used to go ahead and get the object I'm interested in first, and then usually apply something like a match or a map() or foreach() for collections. I like it a lot, since it now feels like a more natural and more to-the-point way of structuring my code.
Little by little, I've wished I could program the same way for conditions; i.e., obtain a Boolean value first, and then match it to do various things. A full-blown match, however, does seem a bit overkill for this task.
Compare:
obj.isSomethingValid match {
case true => doX
case false => doY
}
vs. what I would write with style closer to Java:
if (obj.isSomethingValid)
doX
else
doY
Then I remembered Smalltalk's ifTrue: and ifFalse: messages (and variants thereof). Would it be possible to write something like this in Scala?
obj.isSomethingValid ifTrue doX else doY
with variants:
val v = obj.isSomethingValid ifTrue someVal else someOtherVal
// with side effects
obj.isSomethingValid ifFalse {
numInvalid += 1
println("not valid")
}
Furthermore, could this style be made available to simple, two-state types like Option? I know the more idiomatic way to use Option is to treat it as a collection and call filter(), map(), exists() on it, but often, at the end, I find that I want to perform some doX if it is defined, and some doY if it isn't. Something like:
val ok = resultOpt ifSome { result =>
println("Obtained: " + result)
updateUIWith(result) // returns Boolean
} else {
numInvalid += 1
println("missing end result")
false
}
To me, this (still?) looks better than a full-blown match.
I am providing a base implementation I came up with; general comments on this style/technique and/or better implementations are welcome!
First: we probably cannot reuse else, as it is a keyword, and using the backticks to force it to be seen as an identifier is rather ugly, so I'll use otherwise instead.
Here's an implementation attempt. First, use the pimp-my-library pattern to add ifTrue and ifFalse to Boolean. They are parametrized on the return type R and accept a single by-name parameter, which should be evaluated if the specified condition is realized. But in doing so, we must allow for an otherwise call. So we return a new object called Otherwise0 (why 0 is explained later), which stores a possible intermediate result as a Option[R]. It is defined if the current condition (ifTrue or ifFalse) is realized, and is empty otherwise.
class BooleanWrapper(b: Boolean) {
def ifTrue[R](f: => R) = new Otherwise0[R](if (b) Some(f) else None)
def ifFalse[R](f: => R) = new Otherwise0[R](if (b) None else Some(f))
}
implicit def extendBoolean(b: Boolean): BooleanWrapper = new BooleanWrapper(b)
For now, this works and lets me write
someTest ifTrue {
println("OK")
}
But, without the following otherwise clause, it cannot return a value of type R, of course. So here's the definition of Otherwise0:
class Otherwise0[R](intermediateResult: Option[R]) {
def otherwise[S >: R](f: => S) = intermediateResult.getOrElse(f)
def apply[S >: R](f: => S) = otherwise(f)
}
It evaluates its passed named argument if and only if the intermediate result it got from the preceding ifTrue or ifFalse is undefined, which is exactly what is wanted. The type parametrization [S >: R] has the effect that S is inferred to be the most specific common supertype of the actual type of the named parameters, such that for instance, r in this snippet has an inferred type Fruit:
class Fruit
class Apple extends Fruit
class Orange extends Fruit
val r = someTest ifTrue {
new Apple
} otherwise {
new Orange
}
The apply() alias even allows you to skip the otherwise method name altogether for short chunks of code:
someTest.ifTrue(10).otherwise(3)
// equivalently:
someTest.ifTrue(10)(3)
Finally, here's the corresponding pimp for Option:
class OptionExt[A](option: Option[A]) {
def ifNone[R](f: => R) = new Otherwise1(option match {
case None => Some(f)
case Some(_) => None
}, option.get)
def ifSome[R](f: A => R) = new Otherwise0(option match {
case Some(value) => Some(f(value))
case None => None
})
}
implicit def extendOption[A](opt: Option[A]): OptionExt[A] = new OptionExt[A](opt)
class Otherwise1[R, A1](intermediateResult: Option[R], arg1: => A1) {
def otherwise[S >: R](f: A1 => S) = intermediateResult.getOrElse(f(arg1))
def apply[S >: R](f: A1 => S) = otherwise(f)
}
Note that we now also need Otherwise1 so that we can conveniently passed the unwrapped value not only to the ifSome function argument, but also to the function argument of an otherwise following an ifNone.
You may be looking at the problem too specifically. You would probably be better off with the pipe operator:
class Piping[A](a: A) { def |>[B](f: A => B) = f(a) }
implicit def pipe_everything[A](a: A) = new Piping(a)
Now you can
("fish".length > 5) |> (if (_) println("Hi") else println("Ho"))
which, admittedly, is not quite as elegant as what you're trying to achieve, but it has the great advantage of being amazingly versatile--any time you want to put an argument first (not just with booleans), you can use it.
Also, you already can use options the way you want:
Option("fish").filter(_.length > 5).
map (_ => println("Hi")).
getOrElse(println("Ho"))
Just because these things could take a return value doesn't mean you have to avoid them. It does take a little getting used to the syntax; this may be a valid reason to create your own implicits. But the core functionality is there. (If you do create your own, consider fold[B](f: A => B)(g: => B) instead; once you're used to it the lack of the intervening keyword is actually rather nice.)
Edit: Although the |> notation for pipe is somewhat standard, I actually prefer use as the method name, because then def reuse[B,C](f: A => B)(g: (A,B) => C) = g(a,f(a)) seems more natural.
Why don't just use it like this:
val idiomaticVariable = if (condition) {
firstExpression
} else {
secondExpression
}
?
IMO, its very idiomatic! :)
I have a recursive function that takes a Map as single parameter. It then adds new entries to that Map and calls itself with this larger Map. Please ignore the return values for now. The function isn't finished yet. Here's the code:
def breadthFirstHelper( found: Map[AIS_State,(Option[AIS_State], Int)] ): List[AIS_State] = {
val extension =
for(
(s, v) <- found;
next <- this.expand(s) if (! (found contains next) )
) yield (next -> (Some(s), 0))
if ( extension.exists( (s -> (p,c)) => this.isGoal( s ) ) )
List(this.getStart)
else
breadthFirstHelper( found ++ extension )
}
In extension are the new entries that shall get added to the map. Note that the for-statement generates an iterable, not a map. But those entries shall later get added to the original map for the recursive call. In the break condition, I need to test whether a certain value has been generated inside extension. I try to do this by using the exists method on extension. But the syntax for extracting values from the map entries (the stuff following the yield) doesn't work.
Questions:
How do I get my break condition (the boolean statement to the if) to work?
Is it a good idea to do recursive work on a immutable Map like this? Is this good functional style?
When using a pattern-match (e.g. against a Tuple2) in a function, you need to use braces {} and the case statement.
if (extension.exists { case (s,_) => isGoal(s) } )
The above also uses the fact that it is more clear when matching to use the wildcard _ for any allowable value (which you subsequently do not care about). The case xyz gets compiled into a PartialFunction which in turn extends from Function1 and hence can be used as an argument to the exists method.
As for the style, I am not functional programming expert but this seems like it will be compiled into a iterative form (i.e. it's tail-recursive) by scalac. There's nothing which says "recursion with Maps is bad" so why not?
Note that -> is a method on Any (via implicit conversion) which creates a Tuple2 - it is not a case class like :: or ! and hence cannot be used in a case pattern match statement. This is because:
val l: List[String] = Nil
l match {
case x :: xs =>
}
Is really shorthand/sugar for
case ::(x, xs) =>
Similarly a ! b is equivalent to !(a, b). Of course, you may have written your own case class ->...
Note2: as Daniel says below, you cannot in any case use a pattern-match in a function definition; so while the above partial function is valid, the following function is not:
(x :: xs) =>
This is a bit convoluted for me to follow, whatever Oxbow Lakes might think.
I'd like first to clarify one point: there is no break condition in for-comprehensions. They are not loops like C's (or Java's) for.
What an if in a for-comprehension means is a guard. For instance, let's say I do this:
for {i <- 1 to 10
j <- 1 to 10
if i != j
} yield (i, j)
The loop isn't "stopped" when the condition is false. It simply skips the iterations for which that condition is false, and proceed with the true ones. Here is another example:
for {i <- 1 to 10
j <- 1 to 10
if i % 2 != 0
} yield (i, j)
You said you don't have side-effects, so I can skip a whole chapter about side effects and guards on for-comprehensions. On the other hand, reading a blog post I made recently on Strict Ranges is not a bad idea.
So... give up on break conditions. They can be made to work, but they are not functional. Try to rephrase the problem in a more functional way, and the need for a break condition will be replaced by something else.
Next, Oxbow is correct in that (s -> (p,c) => isn't allowed because there is no extractor defined on an object called ->, but, alas, even (a :: b) => would not be allowed, because there is no pattern matching going on in functional literal parameter declaration. You must simply state the parameters on the left side of =>, without doing any kind of decomposition. You may, however, do this:
if ( extension.exists( t => val (s, (p,c)) = t; this.isGoal( s ) ) )
Note that I replaced -> with ,. This works because a -> b is a syntactic sugar for (a, b), which is, itself, a syntactic sugar for Tuple2(a, b). As you don't use neither p nor c, this works too:
if ( extension.exists( t => val (s, _) = t; this.isGoal( s ) ) )
Finally, your recursive code is perfectly fine, though probably not optimized for tail-recursion. For that, you either make your method final, or you make the recursive function private to the method. Like this:
final def breadthFirstHelper
or
def breadthFirstHelper(...) {
def myRecursiveBreadthFirstHelper(...) { ... }
myRecursiveBreadthFirstHelper(...)
}
On Scala 2.8 there is an annotation called #TailRec which will tell you if the function can be made tail recursive or not. And, in fact, it seems there will be a flag to display warnings about functions that could be made tail-recursive if slightly changed, such as above.
EDIT
Regarding Oxbow's solution using case, that's a function or partial function literal. It's type will depend on what the inference requires. In that case, because that's that exists takes, a function. However, one must be careful to ensure that there will always be a match, otherwise you get an exception. For example:
scala> List(1, 'c') exists { case _: Int => true }
res0: Boolean = true
scala> List(1, 'c') exists { case _: String => true }
scala.MatchError: 1
at $anonfun$1.apply(<console>:5)
... (stack trace elided)
scala> List(1, 'c') exists { case _: String => true; case _ => false }
res3: Boolean = false
scala> ({ case _: Int => true } : PartialFunction[AnyRef,Boolean])
res5: PartialFunction[AnyRef,Boolean] = <function1>
scala> ({ case _: Int => true } : Function1[Int, Boolean])
res6: (Int) => Boolean = <function1>
EDIT 2
The solution Oxbow proposes does use pattern matching, because it is based on function literals using case statements, which do use pattern matching. When I said it was not possible, I was speaking of the syntax x => s.