Scalaz Kleisli question - scala

There is a trait called Kleisli in the scalaz library. Looking at the code:
import scalaz._
import Scalaz._
type StringPair = (String, String)
val f: Int => List[String] = (i: Int) => List((i |+| 1).toString, (i |+| 2).toString)
val g: String => List[StringPair] = (s: String) => List("X" -> s, s -> "Y")
val k = kleisli(f) >=> kleisli(g) //this gives me a function: Int => List[(String, String)]
Calling the function k with the value of 2 gives:
println( k(2) ) //Prints: List((X,3), (3,Y), (X,4), (4,Y))
My question is: how would I use Scalaz to combine f and g to get a function m such that the output of m(2) would be:
val m = //??? some combination of f and g
println( m(2) ) //Prints: List((X,3), (X,4), (3,Y), (4,Y))
Is this even possible?

Seems like you want transpose. Scalaz doesn't supply this, but it should be easy to write. The function m that you want is val m = f andThen (_.map(g)) andThen transpose andThen (_.join)

Related

How to apply a function to a matrix?

This is a follow-up to my previous question
Now I know that cats provides an instance of Apply for Vector. So I can write:
import cats.implicits._
scala> val f: Int => Int = _ + 2
f: Int => Int = <function1>
scala> Vector(f) ap Vector(1, 2, 3)
res18: scala.collection.immutable.Vector[Int] = Vector(3, 4, 5)
Now I wonder how apply to f to all elements of a matrix defined as Vector[Vector[Int]. Does cats provide an Apply instance for matrices ?
In order to use ap on Vector[Vector[Int]], you'll need f lifted to a Vector[Vector[A => B]]. One possible way is:
import cats.Apply
import cats.implicits._
val f: Int => Int = _ + 2
val vectorOfVectors = Apply[Vector] compose Apply[Vector]
val vec = Vector(Vector(1,2), Vector(3,4))
val res: Vector[Vector[Int]] = vectorOfVectors.ap(Vector(Vector(f)))(vec)
Yields:
Vector(3, 4)
Vector(5, 6)
A nicer way IMO is to use Nested:
Using kind-projector in build.sbt:
addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.4")
And then:
import cats.Functor
import cats.data.Nested
import cats.implicits._
val f: Int => Int = _ + 2
val vec = Vector(Vector(1,2), Vector(3,4))
val nested: Nested[Vector, Vector, Int] = Nested(vec)
val res: Nested[Vector, Vector, Int] = Functor[Nested[Vector, Vector, ?]].map(nested)(f)
val result: Vector[Vector[Int]] = res.value
Note how using Nested means we can apply f with no lifting at all.

fully applying functions in Scala, shorthand notation impossible?

Is there a way to declare a fully-applied function without a full new lambda?
scala> val F = (x: Int) => math.pow(x,2)
F: Int => Double = <function1>
scala> val G = F(3)
G: Double = 9.0
How can I declare it such that G is an:
() => Double = <function0>
Without doing this:
scala> val G = () => F(3)
G: () => Double = <function0>
? The _ notation doesn't seem to do the trick:
scala> val G = F(3) _
<console>:8: error: _ must follow method; cannot follow Double
val G = F(3) _
There is no way. The shortest form is what you came up with, i.e., () => F(3).

Currying Example in Scala

Is the following a good example of currying?
def sum(a: Int, b: Int) : (Int => Int) = {
def go(a: Int) : Int = {
a + b;
}
go
}
I half understand the below results, but how could I write (or maybe how I should've written) sum() in a curried way?
scala> sum(3,4) res0: Int => Int = <function1>
scala> sum(3,4).apply(2) res1: Int = 6
scala> sum(3,4).apply(3) res2: Int = 7
Currying mechanism was introduced in Scala to support type inference. For example foldLeft function in the standard lib:
def foldLeft[B](z: B)(op: (B, A) => B): B
Without currying you must provide types explicitly:
def foldLeft[B](z: B, op: (B, A) => B): B
List("").foldLeft(0, (b: Int, a: String) => a + b.length)
List("").foldLeft[Int](0, _ + _.length)
There are three ways to write a curried function:
1) Write it in currying form:
def sum(a: Int)(b: Int) = a + b
which is just syntactic sugar for:
def sum(a: Int): Int => Int = b => a + b
2) Call curried on the function object (sum _).curried and check the types:
sum: (a: Int, b: Int)Int
res10: Int => (Int => Int) = <function1>
In your example, you can use Scala type inference to reduce the amount of code and change your code:
def sum(a: Int, b: Int) : (Int => Int) = {
def go(a: Int) : Int = {
a + b;
}
go
}
into:
def sum(a: Int, b: Int) : (Int => Int) = c => a + b + c
semantically these are the same, because you explicitly provided the return type, so Scala knows that you will return a function wich takes an Int argument and return an Int
Also a more complete answer about curring was given by retronym
In the lambda calculus, you have something called a lambda abstraction λx.term1 which when applied to another term (λx.term1)(term2), corresponds to the concept of applying a function to term2. The lambda calculus is the theoritical basis for functional programming. In lambda calculus, you don't have lambda abstraction taking multiple parameters. So how you do you represent functions of two arguments? The answer is to return a function that will take the other argument and then return the result on both argument.
So in Scala, if you have a var a in scope, you can return a function that will add its argument b to a:
scala> var a = 1
a: Int = 1
scala> val adda = (b: Int) => a + b
adda: Int => Int = <function1>
scala> adda(3)
res1: Int = 4
Now if you have an argument a in scope it works just as well:
scala> val sum = (a: Int) => (b: Int) => a + b
sum: Int => Int => Int = <function1>
scala> sum(3)(5)
res2: Int = 8
So without having access to a syntax that lets you define a function of two arguments, you just basically achieve that with a function sum taking an argument a returning a function equivalent to adda that takes a argument b and returns a + b. And that's called currying.
As an exercise, define a function using currying that will let you work on 3 arguments. For instance val sum3: Int => Int => Int => Int = ???, and fill in what goes into the question marks.
Disclaimer: I'm pretty new to Scala, so treat this with a grain of salt
In purely functional languages like Haskell currying plays very important role in function composition, e.g. if I want to find sum of squares I would write in Haskell (sorry for too much Haskell, but syntax has similarities with Scala and it's not that hard to guess)
without currying:
sum_of_squares xs = foldl (\x y -> x + y) 0 (map (\x -> x * x) xs)
with curring (. is a function composition):
sum_of_squares = (foldl (\x y -> x + y) 0) . (map (\x -> x * x))
which allows me to operate with functions instead of operating with arguments. It may not be that clear from previous example, but consider this:
sum_of_anything f = (foldl (\x y -> x + y) 0) . (map f)
here f is an arbitrary function and I can rewrite the first example as:
sum_of_squares = sum_of_anything (\x -> x * x)
Now let's go back to Scala. Scala is OO language, so usually xs will be a receiver:
def sum_of_squares(xs: List[Int]): Int = {
xs.map(x => x * x).foldLeft(0)((x, y) => x + y)
}
sum_of_squares(List(1,2,3))
def sum_of_anything(f: (Int, Int) => Int)(xs: List[Int]): Int = {
xs.map(x => x * x).foldLeft(0)(f)
}
sum_of_anything((x, y) => x + y)(List(1, 2, 3))
which means I can't omit xs. I can probably rewrite it with lambdas, but I won't be able to use map and foldLeft without adding more boilerplate. So as other people mentioned in Scala "currying" is probably mostly used to support type inference.
Meanwhile in your particular example I have a feeling that you don't need outer a, it's shadowed anyway, you probably meant:
def sum(b: Int) : (Int => Int) = {
def go(a: Int) : Int = {
a + b;
}
go
}
But in this simple example you can use partial application (given that you will probably pass sum to higher order functions):
List(1, 2, 3).map(sum(2)) //> res0: List[Int] = List(3, 4, 5)
List(1, 2, 3).map(_ + 2) //> res1: List[Int] = List(3, 4, 5)
For this kind of application sum can be shorter because sum(2) will be implicitly expanded to Int => Int:
def sum(b: Int)(a: Int): Int = a + b
This form is not valid for val sum2 = sum(2) though, you will have to write val sum2 = sum(2) _.

Scala: Defining a function to be the correct type

I've been playing around with Scala code and have come up against a compiler error which I don't understand. The code generates a vector of pairs of Ints and then tries to filter it.
val L = for (x <- (1 to 5)) yield (x, x * x)
val f = (x: Int, y: Int) => x > 3
println(L.filter(f))
The compiler complains about trying to use f as an argument for the filter method with the compiler error message being:
error: type mismatch;
found : (Int, Int) => Boolean
required: ((Int, Int)) => Boolean
How do I define the function f correctly to satisfy the required function type? I tried to add extra parentheses around (x: Int, y: Int) but this gave:
error: not a legal formal parameter
val f = ((x: Int, y: Int)) => x > 3
^
f has type Function2[Int, Int, Boolean]. L's type is IndexedSeq[Tuple2[Int, Int]] and so filter expects a function of type Function1[Tuple2[Int, Int], Boolean]. Every FunctionN[A, B, .., R] trait has a method tupled, which returns a function of type Function1[TupleN[A, B, ..], R]. You can use it here to transform f to the type expected by L.filter.
println(L.filter(f.tupled))
> Vector((4,16), (5,25))
Alternatively you can redefine f to be a Function1[Tuple2[Int, Int], Boolean] as follows and use it directly.
val f = (t: (Int, Int)) => t._1 > 3
println(L.filter(f))
> Vector((4,16), (5,25))
val f = (xy: (Int, Int)) => xy._1 > 3
println (L.filter (f))
If you do
val f = (x: Int, y: Int) => x > 3
you define a function which takes two ints, which is not the same as a function which takes a pair of ints as parameter.
Compare:
scala> val f = (x: Int, y: Int) => x > 3
f: (Int, Int) => Boolean = <function2>
scala> val f = (xy: (Int, Int)) => xy._1 > 3
f: ((Int, Int)) => Boolean = <function1>
If you don't want to rewrite your function to explicitely useing Tuple2 (as suggested by missingfaktor and user unknown), you can define a implicit method to do it automatically. This lets the function f untouched (you aren't forced to always call it with a Tuple2 parameter) and easier to understand, because you still use the identifiers x and y.
implicit def fun2ToTuple[A,B,Res](f:(A,B)=>Res):((A,B))=>Res =
(t:(A,B)) => f(t._1, t._2)
val L = for (x <- (1 to 5)) yield (x, x * x)
val f = (x: Int, y: Int) => x > 3
val g = (x: Int, y: Int) => x % 2 > y % 3
L.filter(f) //> Vector((4,16), (5,25))
L.filter(g) //> Vector((3,9))
f(0,1) //> false
f((4,2)) //> true
Now every Function2 can also be used as a Function1 with an Tuple2 as parameter, because it uses the implicit method to convert the function if needed.
For functions with more than two parameters the implicit defs looks similiar:
implicit def fun3ToTuple[A,B,C,Res](f:(A,B,C)=>Res):((A,B,C))=>Res =
(t:(A,B,C)) => f(t._1, t._2, t._3)
implicit def fun4ToTuple[A,B,C,D,Res](f:(A,B,C,D)=>Res):((A,B,C,D))=>Res =
(t:(A,B,C,D)) => f(t._1, t._2, t._3, t._4)
...

scalaz List[StateT].sequence - could not find implicit value for parameter n: scalaz.Applicative

I'm trying to figure out how to use StateT to combine two State state transformers based on a comment on my Scalaz state monad examples answer.
It seems I'm very close but I got an issue when trying to apply sequence.
import scalaz._
import Scalaz._
import java.util.Random
val die = state[Random, Int](r => (r, r.nextInt(6) + 1))
val twoDice = for (d1 <- die; d2 <- die) yield (d1, d2)
def freqSum(dice: (Int, Int)) = state[Map[Int,Int], Int]{ freq =>
val s = dice._1 + dice._2
val tuple = s -> (freq.getOrElse(s, 0) + 1)
(freq + tuple, s)
}
type StateMap[x] = State[Map[Int,Int], x]
val diceAndFreqSum = stateT[StateMap, Random, Int]{ random =>
val (newRandom, dice) = twoDice apply random
for (sum <- freqSum(dice)) yield (newRandom, sum)
}
So I got as far as having a StateT[StateMap, Random, Int] that I can unwrap with initial random and empty map states:
val (freq, sum) = diceAndFreqSum ! new Random(1L) apply Map[Int,Int]()
// freq: Map[Int,Int] = Map(9 -> 1)
// sum: Int = 9
Now I'd like to generate a list of those StateT and use sequence so that I can call list.sequence ! new Random(1L) apply Map[Int,Int](). But when trying this I get:
type StT[x] = StateT[StateMap, Random, x]
val data: List[StT[Int]] = List.fill(10)(diceAndFreqSum)
data.sequence[StT, Int]
//error: could not find implicit value for parameter n: scalaz.Applicative[StT]
data.sequence[StT, Int]
^
Any idea? I can use some help for the last stretch - assuming it's possible.
Ah looking at the scalaz Monad source, I noticed there was an implicit def StateTMonad that confirms that StateT[M, A, x] is a monad for type parameter x. Also monads are applicatives, which was confirmed by looking at the definition of the Monad trait and by poking in the REPL:
scala> implicitly[Monad[StT] <:< Applicative[StT]]
res1: <:<[scalaz.Monad[StT],scalaz.Applicative[StT]] = <function1>
scala> implicitly[Monad[StT]]
res2: scalaz.Monad[StT] = scalaz.MonadLow$$anon$1#1cce278
So this gave me the idea of defining an implicit Applicative[StT] to help the compiler:
type StT[x] = StateT[StateMap, Random, x]
implicit val applicativeStT: Applicative[StT] = implicitly[Monad[StT]]
That did the trick:
val data: List[StT[Int]] = List.fill(10)(diceAndFreqSum)
val (frequencies, sums) =
data.sequence[StT, Int] ! new Random(1L) apply Map[Int,Int]()
// frequencies: Map[Int,Int] = Map(10 -> 1, 6 -> 3, 9 -> 1, 7 -> 1, 8 -> 2, 4 -> 2)
// sums: List[Int] = List(9, 6, 8, 8, 10, 4, 6, 6, 4, 7)