def iter[A](f: A => A, n: Int): A => A = {
if (n == 1) {
f
} else {
f(iter(f,n-1))
}
}
I want to make a function iter that makes function composition of f, for example:
iter(f,1) = f
iter(f,2) = f(f)
But I can't find a way how to pass type A into function f recursively, how can I solve this problem?
Note that in your code f(iter(f,n-1)) where f accept an instance of A but iter(f, n-1) with type A => A.
Here is a solution:
scala> def iter[A](f: A => A, n: Int): A => A =
| if (n == 0) identity else f.compose(iter(f, n-1))
|
def iter[A](f: A => A, n: Int): A => A
scala> iter[Int](x => x + 1, 10)(0)
val res0: Int = 10
Or without compose:
scala> def iter[A](f: A => A, n: Int): A => A =
| if (n == 0) identity else x => iter(f, n-1)(f(x))
Or even simple:
scala> def iter[A](f: A => A, n: Int): A => A = Function.chain(Seq.fill(n)(f))
Related
Just playing around with some Scala 3 features, I'm defining a BooleanAlgebra[A] in which there is T <: A and B <: A. These types are used to check if the type A has been normalized and we no longer need to check the bounds of it.
Normailize gives us T | F
TypeTests are required of course because the types T and F are erased at runtime.
The sample works without a problem, however it complains that the matches are not exhaustive anytime I match against T | F even though there is a TypeTag from T | F => T and from T | F => F. Note I've added println statements so that you can see it work.
Adding TypeTags from A => T | F, A => T and A => F don't work either.
N is required due to the fact that Scala 3 doesn't seem to like to do this calculation over something that can change. In the Peano example on the Dotty site, if you switch it to Peano[A] it will stop matching properly, but if you add type NAT = A it works fine.
Any thoughts about how this can be made to match properly would be appreciated.
Here is the code sample:
trait BooleanAlgebra[A] {
final type N = A
type T <: N
type F <: N
val tru: T
val fls: F
final given TypeTest[T | F, T] =
x =>
println(" => T")
if x == tru then Some(tru.asInstanceOf[x.type & T])
else None
final given TypeTest[T | F, F] =
x =>
println(" => F")
if x == fls then Some(fls.asInstanceOf[x.type & F])
else None
def normalize(value: N): T | F
final def not(value: T | F): T | F =
value match
case _: T => fls
case _: F => tru
final def and(lhs: => T | F, rhs: => T | F): T | F =
lhs match
case _: T => rhs
case _: F => fls
final def or(lhs: => T | F, rhs: => T | F): T | F =
lhs match
case _: T => tru
case _: F => rhs
extension (lhs: => T | F) {
final def unary_! : T | F =
not(lhs)
final def |(rhs: => T | F): T | F =
or(lhs, rhs)
final def &(rhs: => T | F): T | F =
and(lhs, rhs)
}
}
object BooleanAlgebra {
def tru[A](using b: BooleanAlgebra[A]): b.T =
b.tru
def fls[A](using b: BooleanAlgebra[A]): b.F =
b.fls
def not[A](using b: BooleanAlgebra[A]): b.T | b.F => b.T | b.F =
value =>
b.not(value)
def norm[A](value: A)(using b: BooleanAlgebra[A]): b.T | b.F =
b.normalize(value)
}
Example implementation
given BooleanAlgebra[Int] with {
type T = 1
type F = 0
val tru = 1
val fls = 0
def normalize(value: Int) =
if value > 0 then tru
else fls
}
With the following code, I'm NOT getting any warnings with scala 3.0.2 (and I WAS getting them with 3.0.0):...
I had to make several minor modifications, first in the trait I've defined N as T | F, and used it everywhere:
trait BooleanAlgebra [A]:
type T <: A
type F <: A
type N = T | F
val tru: T
val fls: F
final given TypeTest [N, T] =
x =>
print ("=> T ")
if x == tru then
Some (tru.asInstanceOf [x.type & T])
else
None
final given TypeTest [N, F] =
x =>
print ("=> F ")
if x == fls then
Some (fls.asInstanceOf [x.type & F])
else
None
def normalize (value: A): N
final def not (v1: => N): N =
v1 match
case _: T => fls
case _: F => tru
final def and (v1: => N, v2: => N): N =
v1 match
case _: T => v2
case _: F => fls
final def or (v1: => N, v2: => N): N =
v1 match
case _: T => tru
case _: F => v2
Then, I've defined extension(s) in the object (so moved them from the trait) in a slightly different manner (had to change names for | and & to prevent calls to existing functions in Int too). Also in the object, I've defined not (which you had), and and or functions (although they are not needed for the test):
object BooleanAlgebra:
def tru [A] (using b: BooleanAlgebra [A]): b.T =
b.tru
def fls [A] (using b: BooleanAlgebra [A]): b.F =
b.fls
def norm [A] (value: A) (using b: BooleanAlgebra [A]): b.N =
b.normalize (value)
extension [A] (using b: BooleanAlgebra [A]) (v1: => b.N)
{
final def unary_! : b.N =
b.not (v1)
final def &&& (v2: => b.N): b.N =
b.and (v1, v2)
final def ||| (v2: => b.N): b.N =
b.or (v1, v2)
}
def not [A] (using b: BooleanAlgebra [A]): b.N => b.N =
v1 => b.not (v1)
def and [A] (using b: BooleanAlgebra [A]): (b.N, b.N) => b.N =
(v1, v2) => b.and (v1, v2)
def or [A] (using b: BooleanAlgebra [A]): (b.N, b.N) => b.N =
(v1, v2) => b.or (v1, v2)
Example usage, with:...
given BooleanAlgebra [Int] with
type T = 1
type F = 0
val tru = 1
val fls = 0
def normalize (value: Int): N =
if (value > 0) then 1 else 0
I can do something like this for example (comments regarding use of TypeTest within code):...
def test () (using ba: BooleanAlgebra [Int]): Unit =
import ba._
val a1 = 4
val n1 = normalize (a1)
// this will print normalized value of 1
println (n1)
// following not call will make a single type test for T
val n2 = !n1
println (n2)
// following two calls will make 1 type test each, for T only
println (n1 &&& n2)
println (n1 ||| n2)
// following two calls will make 2 type tests each, both for T (failing) and then F
println (n2 &&& n1)
println (n2 ||| n1)
How to emulate following behavior in Scala? i.e. keep folding while some certain conditions on the accumulator are met.
def foldLeftWhile[B](z: B, p: B => Boolean)(op: (B, A) => B): B
For example
scala> val seq = Seq(1, 2, 3, 4)
seq: Seq[Int] = List(1, 2, 3, 4)
scala> seq.foldLeftWhile(0, _ < 3) { (acc, e) => acc + e }
res0: Int = 1
scala> seq.foldLeftWhile(0, _ < 7) { (acc, e) => acc + e }
res1: Int = 6
UPDATES:
Based on #Dima answer, I realized that my intention was a little bit side-effectful. So I made it synchronized with takeWhile, i.e. there would be no advancement if the predicate does not match. And add some more examples to make it clearer. (Note: that will not work with Iterators)
First, note that your example seems wrong. If I understand correctly what you describe, the result should be 1 (the last value on which the predicate _ < 3 was satisfied), not 6
The simplest way to do this is using a return statement, which is very frowned upon in scala, but I thought, I'd mention it for the sake of completeness.
def foldLeftWhile[A, B](seq: Seq[A], z: B, p: B => Boolean)(op: (B, A) => B): B = foldLeft(z) { case (b, a) =>
val result = op(b, a)
if(!p(result)) return b
result
}
Since we want to avoid using return, scanLeft might be a possibility:
seq.toStream.scanLeft(z)(op).takeWhile(p).last
This is a little wasteful, because it accumulates all (matching) results.
You could use iterator instead of toStream to avoid that, but Iterator does not have .last for some reason, so, you'd have to scan through it an extra time explicitly:
seq.iterator.scanLeft(z)(op).takeWhile(p).foldLeft(z) { case (_, b) => b }
It is pretty straightforward to define what you want in scala. You can define an implicit class which will add your function to any TraversableOnce (that includes Seq).
implicit class FoldLeftWhile[A](trav: TraversableOnce[A]) {
def foldLeftWhile[B](init: B)(where: B => Boolean)(op: (B, A) => B): B = {
trav.foldLeft(init)((acc, next) => if (where(acc)) op(acc, next) else acc)
}
}
Seq(1,2,3,4).foldLeftWhile(0)(_ < 3)((acc, e) => acc + e)
Update, since the question was modified:
implicit class FoldLeftWhile[A](trav: TraversableOnce[A]) {
def foldLeftWhile[B](init: B)(where: B => Boolean)(op: (B, A) => B): B = {
trav.foldLeft((init, false))((a,b) => if (a._2) a else {
val r = op(a._1, b)
if (where(r)) (op(a._1, b), false) else (a._1, true)
})._1
}
}
Note that I split your (z: B, p: B => Boolean) into two higher-order functions. That's just a personal scala style preference.
What about this:
def foldLeftWhile[A, B](z: B, xs: Seq[A], p: B => Boolean)(op: (B, A) => B): B = {
def go(acc: B, l: Seq[A]): B = l match {
case h +: t =>
val nacc = op(acc, h)
if(p(nacc)) go(op(nacc, h), t) else nacc
case _ => acc
}
go(z, xs)
}
val a = Seq(1,2,3,4,5,6)
val r = foldLeftWhile(0, a, (x: Int) => x <= 3)(_ + _)
println(s"$r")
Iterate recursively on the collection while the predicate is true, and then return the accumulator.
You cand try it on scalafiddle
After a while I received a lot of good looking answers. So, I combined them to this single post
a very concise solution by #Dima
implicit class FoldLeftWhile[A](seq: Seq[A]) {
def foldLeftWhile[B](z: B)(p: B => Boolean)(op: (B, A) => B): B = {
seq.toStream.scanLeft(z)(op).takeWhile(p).lastOption.getOrElse(z)
}
}
by #ElBaulP (I modified a little bit to match comment by #Dima)
implicit class FoldLeftWhile[A](seq: Seq[A]) {
def foldLeftWhile[B](z: B)(p: B => Boolean)(op: (B, A) => B): B = {
#tailrec
def foldLeftInternal(acc: B, seq: Seq[A]): B = seq match {
case x :: _ =>
val newAcc = op(acc, x)
if (p(newAcc))
foldLeftInternal(newAcc, seq.tail)
else
acc
case _ => acc
}
foldLeftInternal(z, seq)
}
}
Answer by me (involving side effects)
implicit class FoldLeftWhile[A](seq: Seq[A]) {
def foldLeftWhile[B](z: B)(p: B => Boolean)(op: (B, A) => B): B = {
var accumulator = z
seq
.map { e =>
accumulator = op(accumulator, e)
accumulator -> e
}
.takeWhile { case (acc, _) =>
p(acc)
}
.lastOption
.map { case (acc, _) =>
acc
}
.getOrElse(z)
}
}
Fist exemple: predicate for each element
First you can use inner tail recursive function
implicit class TravExt[A](seq: TraversableOnce[A]) {
def foldLeftWhile[B](z: B, f: A => Boolean)(op: (A, B) => B): B = {
#tailrec
def rec(trav: TraversableOnce[A], z: B): B = trav match {
case head :: tail if f(head) => rec(tail, op(head, z))
case _ => z
}
rec(seq, z)
}
}
Or short version
implicit class TravExt[A](seq: TraversableOnce[A]) {
#tailrec
final def foldLeftWhile[B](z: B, f: A => Boolean)(op: (A, B) => B): B = seq match {
case head :: tail if f(head) => tail.foldLeftWhile(op(head, z), f)(op)
case _ => z
}
}
Then use it
val a = List(1, 2, 3, 4, 5, 6).foldLeftWhile(0, _ < 3)(_ + _)
//a == 3
Second example: for accumulator value:
implicit class TravExt[A](seq: TraversableOnce[A]) {
def foldLeftWhile[B](z: B, f: A => Boolean)(op: (A, B) => B): B = {
#tailrec
def rec(trav: TraversableOnce[A], z: B): B = trav match {
case _ if !f(z) => z
case head :: tail => rec(tail, op(head, z))
case _ => z
}
rec(seq, z)
}
}
Or short version
implicit class TravExt[A](seq: TraversableOnce[A]) {
#tailrec
final def foldLeftWhile[B](z: B, f: A => Boolean)(op: (A, B) => B): B = seq match {
case _ if !f(z) => z
case head :: tail => tail.foldLeftWhile(op(head, z), f)(op)
case _ => z
}
}
Simply use a branch condition on the accumulator:
seq.foldLeft(0, _ < 3) { (acc, e) => if (acc < 3) acc + e else acc}
However you will run every entry of the sequence.
I have a problem to make a working version of the Euler project problem 31 with the use of State trait (inspired from scalaz)
First, I have a solution with a mutable HashMap for memoization. It works but i would like to use the State monad, to understand it and to improve my skills.
I have used it with the fibonacci example, but when i attempt to apply the same technique to my case, i have a compiler error that i don't understand.
I use this implementation for State :
trait State[S, A] {
val run: S => (S, A)
def apply(s: S): (S, A) = run(s)
def eval(s: S): A = run(s)._2
def map[B](f: A => B): State[S, B] =
State { s: S =>
val (s1, a) = run(s)
(s1, f(a))
}
def flatMap[B](f: A => State[S, B]): State[S, B] =
State { s: S =>
val (s1, a) = run(s)
f(a)(s1)
}
}
object State {
def apply[S, A](f: S => (S, A)): State[S, A] = new State[S, A] {
final val run = f
}
def init[S, A](a: A) = State { s: S => (s, a) }
def update[S, A](f: S => S): State[S, Unit] = State { s: S => (f(s), ()) }
def gets[S, A](f: S => A): State[S, A] = State { s: S => (s, f(s)) }
}
my attempt to use it is here :
val coins = List(1, 2, 5, 10, 20, 50, 100, 200)
type MemoKey = (List[Int], Int)
type MemoType = Map[MemoKey, Int]
def ways(listCoins: List[Int], amount: Int): Int = {
def ways_impl(coins: List[Int], sum: Int): State[MemoType, Int] = (coins, sum) match {
case (Nil, 0) => State.init(1)
case (Nil, _) => State.init(0)
case (c :: cs, _) =>
for {
memoed <- State.gets { m: MemoType => m.get((coins, sum)) }
res <- memoed match {
case Some(way) => State.init[MemoType, Int](way)
case None =>
(for {
i <- 0 to sum / c
r <- ways_impl(cs, sum - i * c)
_ <- State.update { m: MemoType => m + ((coins, sum) -> r) }
} yield r).sum
}
} yield res
}
ways_impl(listCoins, amount) eval (Map())
I have a compiler error at this line :
r <- ways_impl(cs, sum - i * c)
The compiler said :
type mismatch; found : State[MemoType,Int] (which expands to) State[scala.collection.immutable.Map[(List[Int], Int),Int],Int] required: scala.collection.GenTraversableOnce[?]
For information, here is my first version with mutable map :
import scala.collection.mutable._
val memo = HashMap[(List[Int], Int), Int]()
val coins = List(1, 2, 5, 10, 20, 50, 100, 200)
def memoWays(coins: List[Int], sum: Int): Int = {
memo.getOrElse((coins, sum), {
val y = ways(coins, sum)
memo += ((coins, sum) -> y)
y
})
}
// brute force method with memoization
def ways(coins: List[Int], sum: Int): Int = (coins, sum) match {
case (Nil, 0) => 1
case (Nil, _) => 0
case (c :: cs, n) =>
(for {
i <- 0 to n / c
r = memoWays(cs, n - i * c)
} yield r).sum
}
println(s"result=${Mesure(ways(coins, 200))}")
What does that error mean ? Why the compiler want a GenTraversableOnce instead of State ?
What kind of thing i don't understand on State monad ?
And, if i may, I have an optional question :
Is my way to memoize with State Monad, is a good choice, or my first implementation with mutable map is better anyway ?
The problem is that your for comprehension is attempting to flatMap two unrelated types: a Range and a State. You're going to have to refactor, although off the top of my head, it's not clear to me how you'll be able to leverage State in a simple way. I'd probably use an immutable Map for the memo, a List to represent the future iterations to be tried, and simple recursion to iterate.
object MatchTest4 extends App{
def matchTest(x: Any): Any = x match {
case 1 => def num(p: Int, q: Int): Unit = {
val sum = p + q
println(sum)
}
case 2 => def num(p: Int, q: Int): Unit = {
val sub = p - q
println(sub)
}
case 3 => def num(p: Int, q: Int): Unit = {
val mul = p * q
println(mul)
}
case 4 => def num(p: Int, q: Int): Unit = {
val div = p / q
println(div)
}
case _ => println("Invalid Choice")
}
println("Enter Your Choice")
val b= readInt()
println(matchTest(b))
}
Now I want to give parameter to the function num().Is it possible?
The below code should accomplish what you are trying to do. The changes I made were:
Removed the return type for the matchTest. Scala will automatically infer the return type as a function value.
Replaced the method definitions "num" by anonymous functions.
Modified the signature of your wildcard pattern match to also return a function consistent with other pattern matches. (This is a hack, I hope someone knows a better way)
You can run your returned anonymous functions like matchTest(4)(2,3) etc.
def matchTest(x: Any) = x match {
case 1 => (p: Int, q: Int) => {
val sum = p + q
println(sum)
}
case 2 => (p: Int, q: Int) => {
val sub = p - q
println(sub)
}
case 3 => (p: Int, q: Int) => {
val mul = p * q
println(mul)
}
case 4 => (p: Int, q: Int) => {
val div = p / q
println(div)
}
case _ => println("Invalid Choice"); (a: Int, b: Int) => println("Invalid Choice")
}
If I have:
val f : A => B => C
This is shorthand for:
val f : Function1[A, Function1[B, C]]
How do I get a function g with the signature:
val g : (A, B) => C = error("todo")
(i.e.)
val g : Function2[A, B, C] //or possibly
val g : Function1[(A, B), C]
in terms of f?
scala> val f : Int => Int => Int = a => b => a + b
f: (Int) => (Int) => Int = <function1>
scala> Function.uncurried(f)
res0: (Int, Int) => Int = <function2>
Extending retonym's answer, for completeness
val f : Int => Int => Int = a => b => a + b
val g: (Int, Int) => Int = Function.uncurried(f)
val h: ((Int, Int)) => Int = Function.tupled(g)
The converse functions for both of these operations are also provided on the Function object, so you could write the above backwards, if you wished
val h: ((Int, Int)) => Int = x =>(x._1 + x._2)
val g: (Int, Int) => Int = Function.untupled(h)
val f : Int => Int => Int = g.curried //Function.curried(g) would also work, but is deprecated. Wierd
Just to round out the answer, although there is a library method to do this, it may also be instructive to do it by hand:
scala> val f = (i: Int) => ((s: String) => i*s.length)
f: (Int) => (String) => Int = <function1>
scala> val g = (i: Int, s: String) => f(i)(s)
g: (Int, String) => Int = <function2>
Or in general,
def uncurry[A,B,C](f: A=>B=>C): (A,B)=>C = {
(a: A, b: B) => f(a)(b)
}
Similar to the answer by Rex Kerr but easier to read.
type A = String
type B = Int
type C = Boolean
val f: A => B => C = s => i => s.toInt+i > 10
val f1: (A, B) => C = f(_)(_)