How to use currying? - coconut

I am playing with Coconut. In my code, I would like to write apply a function on each item of a list. In Coconut, like in Python, I can write:
square = map(x -> x ** 2, [1,2,3]) |> list
square |> print
Try it online!
As a functional language, I expect to be able to use currying. For example in F#, this will work as expected:
let square = [1;2;3] |> List.map(fun x -> x * x)
square |> printfn "%A"
Try it online!
I have the following error when I try:
square = [1,2,3] |> map(x -> x ** 2) |> list
square |> print
error:
TypeError: map() must have at least two arguments.
Try it online!
The message is clear. map() did not receive the second argument. How to use currying in Coconut?

The official Coconut's documentation has an entry about currying (also named Partial application). It is possible. From the documentation:
Coconut uses a $ sign right after a function’s name but before the open parenthesis used to call the function to denote partial application.
Coconut’s partial application also supports the use of a ? to skip partially applying an argument, deferring filling in that argument until the partially-applied function is called. This is useful if you want to partially apply arguments that aren’t first in the argument order.
example:
expnums \= range(5) |> map$(pow$(?, 2))
expnums |> list |> print
In your case, you can write:
square = [1,2,3] |> map$(x -> x ** 2) |> list
square |> print
Try it online!

Related

More efficient use of STStrMap

Is there a more efficient way of using the values in a STStrMap, other than freezeST to get the StrMap first? For example, I have a STStrMap which contain a bunch of functions. At some point, I want to call all the functions, returning the first Just value. This code works:
runOpeners uri omap = do
strmap <- omap >>= \omap' -> freezeST omap' -- convert from STStrMap to StrMap
 pure $ foldl (\acc o -> acc <|> o uri ) Nothing $ values strmap -- call opener functions
But freezeST copies the map first, which is inefficient.

Scala operator associativity (2nd parameter lists)

Is it possible to call an apply function directly on the result of a method which takes a second parameter list (with an implicit arg)? Even with parentheses in the logical place, I get the same compile-time type error, which indicates it doesn't parse it as expected.
val x = Map(1 -> 2, 2->4, 3-> 6) //1
val y = x.map(_.swap) //2
y(4) //3
x.map(_.swap)(4) //4
((x.map(_.swap))(4) //5
Line 4 makes sense to not parse since the (4) easily appears to be the second parameter list for map(), but line 5, there is a set of ()'s around the .map expression, yet it still associates the (4) to the .map rather than the result of .map().
Is there a way to do lines 2 and 3 in one expression?
EDIT: I'm aware of .apply(), which is what the compiler will insert itself. Is there a way to do this without manually de-sugaring?
Yes there are several possible solutions.
All work by either satisfying the implicit parameter list or giving the compiler a hint that expression has ended and the (), read apply, is really the apply-method and no second argument list.
1. Calling .apply()
scala> Map(1 -> 2, 2 -> 4, 3 -> 6).map(_.swap).apply(4)
res7: Int = 2
2. Supplying the implicit directly
Another option is supplying the implicit directly
Example with breakout
import scala.collection.breakOut
scala> List(1).map(_ + 1)(breakOut)(0)
res38: Int = 2
I think the general problem is: You have to fill to provide the implicit for the CanBuildFrom to work properly or explicitly state that you want to call apply and not fill the second parameter list.
You can find more in http://docs.scala-lang.org/tutorials/FAQ/breakout. Opposing to the name the secCanBuildFrom works.

What does `var # _*` signify in Scala

I'm reviewing some Scala code trying to learn the language. Ran into a piece that looks like the following:
case x if x startsWith "+" =>
val s: Seq[Char] = x
s match {
case Seq('+', rest # _*) => r.subscribe(rest.toString){ m => }
}
In this case, what exactly is rest # _* doing? I understand this is a pattern match for a Sequence, but I'm not exactly understanding what that second parameter in the Sequence is supposed to do.
Was asked for more context so I added the code block I found this in.
If you have come across _* before in the form of applying a Seq as varargs to some method/constructor, eg:
val myList = List(args: _*)
then this is the "unapply" (more specifically, search for "unapplySeq") version of this: take the sequence and convert back to a "varargs", then assign the result to rest.
x # p matches the pattern p and binds the result of the whole match to x. This pattern matches a Seq containing '+' followed by any number (*) of unnamed elements (_) and binds rest to a Seq of those elements.

Plus not working in Scala interpreter

I am trying to sum a list using fold in the Scala interpreter, but it keeps giving me a strange error. When I type this:
val list = List(1,2,3)
(list :\ 0)(+)
I expect to get 6. However, the interpreter says
error: illegal start of simple expression
(list :\ 0)(+)
^
If I define my own function
def plus(a: Int, b: Int) = a+b
and call
(list :\ 0)(plus)
I do in fact get 6.
I'm sure I'm missing something really simple here, but I can't figure it out, so any help is much appreciated.
The plus operator by itself is not a function it is a symbol and has no type. What you are looking for is the following
val list = List(1,2,3)
(list :\ 0)(_+_)
The _+_ is shorthand for an anonymous function that takes two parameters and calls the + method on the first parameter passing in the second.
Try this:
(list :\ 0)(_ + _)
You need to use the wildcards to show the Scala compiler that you want to call the "+" method on first of the arguments instead of using the Tuple2 as an argument to a function itself.

How can I write f(g(h(x))) in Scala with fewer parentheses?

Expressions like
ls map (_ + 1) sum
are lovely because they are left-to-right and not nested. But if the functions in question are defined outside the class, it is less pretty.
Following an example I tried
final class DoublePlus(val self: Double) {
def hypot(x: Double) = sqrt(self*self + x*x)
}
implicit def doubleToDoublePlus(x: Double) =
new DoublePlus(x)
which works fine as far as I can tell, other than
A lot of typing for one method
You need to know in advance that you want to use it this way
Is there a trick that will solve those two problems?
You can call andThen on a function object:
(h andThen g andThen f)(x)
You can't call it on methods directly though, so maybe your h needs to become (h _) to transform the method into a partially applied function. The compiler will translate subsequent method names to functions automatically because the andThen method accepts a Function parameter.
You could also use the pipe operator |> to write something like this:
x |> h |> g |> f
Enriching an existing class/interface with an implicit conversion (which is what you did with doubleToDoublePlus) is all about API design when some classes aren't under your control. I don't recommend to do that lightly just to save a few keystrokes or having a few less parenthesis. So if it's important to be able to type val h = d hypot x, then the extra keystrokes should not be a concern. (there may be object allocations concerns but that's different).
The title and your example also don't match:
f(g(h(x))) can be rewritten asf _ compose g _ compose h _ apply x if your concern is about parenthesis or f compose g compose h apply x if f, g, h are function objects rather than def.
But ls map (_ + 1) sum aren't nested calls as you say, so I'm not sure how that relates to the title. And although it's lovely to use, the library/language designers went through a lot of efforts to make it easy to use and under the hood is not simple (much more complex than your hypot example).
def fgh (n: N) = f(g(h(n)))
val m = fgh (n)
Maybe this, observe how a is provided:
def compose[A, B, C](f: B => C, g: A => B): A => C = (a: A) => f(g(a))
basically like the answer above combine the desired functions to a intermediate one which you then can use easily with map.
Starting Scala 2.13, the standard library provides the chaining operation pipe which can be used to convert/pipe a value with a function of interest.
Using multiple pipes we can thus build a pipeline which as mentioned in the title of your question, minimizes the number of parentheses:
import scala.util.chaining._
x pipe h pipe g pipe f