I would like to detect keyboard shortcuts like CTRL+S in Scala. It is easy if only one key is pressed, but it seems to be difficult if two or more keys are pressed. Is there any better solution than the following?
reactions += {
case c # KeyReleased(_, Key.S, _, _) =>
if (c.peer.isControlDown())
// CTRL+S pressed
}
It feels somehow semantically incorrect since it checks if the CTRL button is pressed after the S button is released (and I think it is not really better when you use KeyPressed or KeyTyped).
Here is a SSCE:
import scala.swing._
import scala.swing.event._
object SSCCE extends SimpleSwingApplication {
def top = new MainFrame {
val textArea = new TextArea(3, 30)
contents = new FlowPanel {
contents += textArea
}
listenTo(textArea.keys)
reactions += {
case c # KeyReleased(_, Key.S, _, _) =>
if (c.peer.isControlDown())
Dialog.showMessage(null, "Message", "CTRL+S pressed")
}
}
}
You can check within the pattern match by testing the modifiers:
case c # KeyReleased(_, Key.S, mods, _) if (1 == (1 & mods>>7)) =>
Dialog.showMessage(null, "Message", "CTRL+S pressed")
When Ctrl is down, the bit at index 7 is set.
However, I think your original code is easier to understand.
Adding a helper function would help, of course:
def ctrlDown(mods:Int) = (1 == (1 & mods>>7))
...
case c # KeyReleased(_, Key.S, mods, _) if ctrlDown(mods) =>
Dialog.showMessage(null, "Message", "CTRL+S pressed")
Related
I have the following problem:
I want to write a commandline-tool, where the user can input a command, and after its execution, the menu pops up again for the next command, until the user inserts x.
In Java, I would do it like this (or use a boolean in the Loop, set it and at the end, ask if it is true. However it is not a Java-question, this is just as example to show what I want):
loop1: do{
printMenu();
String input = readFromConsole();
switch(input){
case "a": //dostuff
break;
case "x": break loop1;
}
}while (true);
Since there is no break in Scala, how should I do this?
One way that works is the following:
var cont = true
do{
printMenu()
val cmd = scala.io.StdIn.readLine()
cmd match{
case "c" => {
//dostuff
}
case "x" => cont=false
case _ => println("invalidCommand")
}
}while(cont)
But since loops and mutable variables are not classic functional concepts, I guess there is a better, more Scala-like way.
Another way would be a recursive function, which calls itself everytime "x" is not inserted, but that also doesn't seem to be good style.
How should I do it (what is the best style)?
As mentioned, I already found a working solution, but it seems not really optimal. If it is, just let me know.
Sorry if this is a trivial question, but I searched around and didn't find much about this topic.
Create an infinite iterator and then takeWhile the input isn't the exit command.
Iterator.continually(io.StdIn.readLine)
.takeWhile(_ != "x")
.foreach{
case "this" => /* do this */
case "that" => /* do that */
case _ => /* default */
}
Tail recursion should be sufficient.
#tailrec
final def printMenu():Option[String] = {
println("Put something: ")
val cmd = scala.io.StdIn.readLine()
cmd match{
case "c" => {
return Some("Foo")
}
case "x" => return None
case _ => printMenu()
}
}
printMenu()
Right now IntelliJ's autoformat changes this:
val reduceFn = (left: U, right: U) => {
left ++ right // comment 1
.myFuncA( _._1 ) // comment 2
.myFuncABC { // comment 3
g => { // comment 4
g.myFun
._2
.myFunBBB( 0 )( _ + _ )
}
}
}: U // comment 5
to this:
val reduceFn = (left: U, right: U) => {
left ++ right // comment 1
.myFuncA( _._1 ) // comment 2
.myFuncABC {
// comment 3
g => {
// comment 4
g.myFun
._2
.myFunBBB( 0 )( _ + _ )
}
}
}: U // comment 5
Is there a way I can tell IntelliJ to produce, or, at the very least, not clobber the former style? I don't see comments as an option in Code Style in Editor > Code Style > Scala:
Unfortunately, I don't think this is supported at the moment. There's a ticket for it (SCL-4269), but as of writing there has not been any real activity on it.
You can completely disable the formatter for certain lines by using the formatter control option (cf. Code Style preference page). But that's obviously not a good solution.
I am looking at following snippet. When map-getOrElse and nested patten matching increases in the code it doesn't look so elegant. What better options do you suggest?
case MyMessage =>
val image = (request \ "image").asOpt[String]
image.map { im =>
val conf = (request \ "confirmation").asOpt[String]
conf.map { cf =>
//code to retrieve ride
ride match {
case Some(r) =>
if (booleanCondition) sender ! SuccessCommand(JsBoolean(true), command)
else sender ! FailureCommand("Problem updating", command)
case None => sender ! FailureCommand("Ride empty", command)
}
} getOrElse (sender ! FailureCommand("Missing number", command))
} getOrElse (sender ! FailureCommand("Missing image", command))
Whenever you are mapping over an Option with a function that produces an Option, you should consider whether you should be using flatMap:
def f(x: Int): Option[Int] = Some(x + 1)
f(1).flatMap(x => f(x)).flatMap(y => f(y)) // Some(4)
f(1).flatMap(x => f(x)).flatMap(y => f(y)).getOrElse(0) // 4
You can also use for-comprehensions for this, which is really nice for having clean code when you have long chains of these:
(for(x <- f(1); y <- f(x); z <- f(y)) yield z).getOrElse(0)
Another way to tackle this is to return Either[Command,String] from various helper functions, rather than Option. This would then allow you to use a for comprehension, something like the following:
val result = for {
i <- getImage().right
c <- getConf().right
r <- getRide().right
z <- check(r).right
} yield z
// extract either left or right, whichever is occupied
sender ! result.fold(identity, _ => success())
This has the desired property that we stop as soon as we encounter an error, and capture that specific error - or proceed to a successful conclusion.
I think you should be able to collapse a lot of this into Option.fold(), roughly as follows:
case MyMessage =>
sender !
getImage().fold(fail("Missing image")) { im =>
getConf().fold(fail("Missing number")) { conf => // conf isn't used
getRide().fold(fail("Ride empty")) { r =>
if (booleanCondition) succeed(true)
else fail("Problem updating")
}
}
}
This turns out a bit more concise than flatMap and orElse in this situation (see below)
Option.fold(ifEmpty){f} returns ifEmpty (evaluated lazily) if the option was empty, or evaluates the function f if the option was full.
The above code assumes you create helper functions for getting the various Options (or you could inline the relevant code). It also assumes you pull out the creation of commands into a helper function or two, to avoid all the duplicate references to command.
For comparison, a solution using flatMap looks something like:
case MyMessage =>
sender !
getImage().flatMap { im =>
getConf().flatMap { conf =>
getRide().flatMap { r =>
if (booleanCondition) Some(succeed(true))
else Some(fail("Problem updating"))
}.orElse(Some(fail("Ride Empty")))
}.orElse(Some(fail("Missing number")))
}.getOrElse(fail("Missing image"))
which you could shorten very slightly by having variants of your helper methods (fail and succeed) that return Some[Command] rather than Command
I'm just starting out with the Scala and am trying a little toy program - in this case a text based TicTacToe. I wrote a working version based on what I know about scala, but noticed it was mostly imperative and my classes were mutable.
I'm going through and trying to implement some functional idioms and have managed to at least make the classes representing the game state immutable. However, I'm left with a class responsible for performing the game loop relying on mutable state and imperative loop as follows:
var board: TicTacToeBoard = new TicTacToeBoard
def start() {
var gameState: GameState = new XMovesNext
outputState(gameState)
while (!gameState.isGameFinished) {
val position: Int = getSelectionFromUser
board = board.updated(position, gameState.nextTurn)
gameState = getGameState(board)
outputState(gameState)
}
}
What would be a more idiomatic way to program what I'm doing imperatively in this loop?
Full source code is here https://github.com/whaley/TicTacToe-in-Scala/tree/master/src/main/scala/com/jasonwhaley/tictactoe
imho for Scala, the imperative loop is just fine. You can always write a recursive function to behave like a loop. I also threw in some pattern matching.
def start() {
def loop(board: TicTacToeBoard) = board.state match {
case Finished => Unit
case Unfinished(gameState) => {
gameState.output()
val position: Int = getSelectionFromUser()
loop(board.updated(position))
}
}
loop(new TicTacToeBoard)
}
Suppose we had a function whileSome : (a -> Option[a]) a -> (), which runs the input function until its result is None. That would strip away a little boilerplate.
def start() {
def step(board: TicTacToeBoard) = {
board.gameState.output()
val position: Int = getSelectionFromUser()
board.updated(position) // returns either Some(nextBoard) or None
}
whileSome(step, new TicTacToeBoard)
}
whileSome should be trivial to write; it is simply an abstraction of the former pattern. I'm not sure if it's in any common Scala libs, but in Haskell you could grab whileJust_ from monad-loops.
You could implement it as a recursive method. Here's an unrelated example:
object Guesser extends App {
val MIN = 1
val MAX = 100
readLine("Think of a number between 1 and 100. Press enter when ready")
def guess(max: Int, min: Int) {
val cur = (max + min) / 2
readLine("Is the number "+cur+"? (y/n) ") match {
case "y" => println("I thought so")
case "n" => {
def smallerGreater() {
readLine("Is it smaller or greater? (s/g) ") match {
case "s" => guess(cur - 1, min)
case "g" => guess(max, cur + 1)
case _ => smallerGreater()
}
}
smallerGreater()
}
case _ => {
println("Huh?")
guess(max, min)
}
}
}
guess(MAX, MIN)
}
How about something like:
Stream.continually(processMove).takeWhile(!_.isGameFinished)
where processMove is a function that gets selection from user, updates board and returns new state.
I'd go with the recursive version, but here's a proper implementation of the Stream version:
var board: TicTacToeBoard = new TicTacToeBoard
def start() {
def initialBoard: TicTacToeBoard = new TicTacToeBoard
def initialGameState: GameState = new XMovesNext
def gameIterator = Stream.iterate(initialBoard -> initialGameState) _
def game: Stream[GameState] = {
val (moves, end) = gameIterator {
case (board, gameState) =>
val position: Int = getSelectionFromUser
val updatedBoard = board.updated(position, gameState.nextTurn)
(updatedBoard, getGameState(board))
}.span { case (_, gameState) => !gameState.isGameFinished }
(moves ::: end.take(1)) map { case (_, gameState) => gameState }
}
game foreach outputState
}
This looks weirder than it should. Ideally, I'd use takeWhile, and then map it afterwards, but it won't work as the last case would be left out!
If the moves of the game could be discarded, then dropWhile followed by head would work. If I had the side effect (outputState) instead the Stream, I could go that route, but having side-effect inside a Stream is way worse than a var with a while loop.
So, instead, I use span which gives me both takeWhile and dropWhile but forces me to save the intermediate results -- which can be real bad if memory is a concern, as the whole game will be kept in memory because moves points to the head of the Stream. So I had to encapsulate all that inside another method, game. That way, when I foreach through the results of game, there won't be anything pointing to the Stream's head.
Another alternative would be to get rid of the other side effect you have: getSelectionFromUser. You can get rid of that with an Iteratee, and then you can save the last move and reapply it.
OR... you could write yourself a takeTo method and use that.
Suppose I'm writing a GUI
class Kitteh (val age: Int) {
require (age < 5)
def saveMeow(file: File) = { /* implementation */ }
def savePurr(file: File) = { /* implementation */ }
}
The frame has a field for the current Kitteh, which is an Option because it might not have been defined yet, or the user may have attempted to create an invalid one:
var currentKitteh: Option[Kitteh] = None
Now I want to create a Kitteh safely when the user hits Create
val a = ... // parse age from text box
currentKitteh = try { Some(new Kitteh(a)) } catch { case _ => None }
My GUI has two buttons which do similar things. In psedocode, they should both
if (currentKitteh.isDefined) {
if (file on the disk already exists) {
bring up a dialog box asking for confirmation
if (user confirms)
<< execute method on currentKitteh >>
}
}
else bring up warning dialog
Don't worry about the detail: the point is that because there is code duplication, I want to create a common method that I can call from both buttons. The only difference is the method on the Kitteh that needs to be executed.
Now if currentKitteh were not an Option, the common method could have a signature like
def save(filename: String, f:(File => Unit)) {
which I could call with, for example
save("meow.txt", currentKitteh.saveMeow _)
but since it is actually an Option, how could I implement this?
I could just check whether currentKitteh is defined, and do a .get before calling the save method for each button, but is there another way, leaving this check in the save method? In other words, given an Option[A], is it possible to specify a partial function from a method on the (possibly non-existent) A object?
(hope this question makes sense, convoluted example notwithstanding)
edit: Bonus question: what if, instead of Option[Kitteh], I used Either[Throwable, Kitteh]?
update: Additional line added to pseudocode to bring up warning dialog: ideally, the save method should always be called so that the user is warned if there is no valid Kitteh to save.
This looks like the best option to me:
currentKitteh foreach { c => save("meow.txt", c.saveMeow _) }
If you're repeatedly doing this, you can abstract it,
def currentSaveMeow(file: String) = currentKitteh foreach { c =>
save(file, c.saveMeow _)
}
currentSaveMeow("meow.txt")
I suppose to answer your original question, you could also push the logic into the function argument,
save("meow.txt", file => currentKitten.foreach(_.saveMeow(file)))
The semantics are a little different with this version.
Update. If k: Option[Kitteh] is replaced by k: Either[Throwable, Kitteh], then what about k.right foreach { c => ... }? You could also use k.right map ... if you want to preserve error information.
In response to the modified question, here's another abstraction possibility,
def save(filename: String, f: (Kitteh, File) => Unit)
Now save has the responsibility of unpacking currentKitteh. Call save like this,
save("meow.txt", (k, f) => k.saveMeow(f))
or like this,
save("meow.txt", _ saveMeow _)
You can map a function to it and getOrElse your fail function:
def save =
o map {s => () => "saved a kitteh! " + s} getOrElse {() => "oh noes, no kittehs!"}
then you just:
save()
You could define a class BadKitteh and have that produce error messages. Then simply use currentKitty.getOrElse(badKitty) if you need one.