Suppose I have 2 methods:
def a(s: String) = s + "..."
def b(s: String) = s + ",,,"
And I want to create 3rd method which will call both methods:
def c (s: String) = a(b(s))
How I can do it in idiomatic Scala way?
I think it's better to aggregate this functions into some List and then sequentially apply them:
List(a_, b_)
I think it's better to aggregate this functions into some List and
then sequentially apply them.
You get some help by specifying an expected type:
scala> val fs: List[String => String] = List(a,b)
fs: List[String => String] = List(<function1>, <function1>)
scala> fs.foldLeft("something")((s,f) => f(s))
res0: String = something...,,,
Here is how you can combine a set of functions into one:
// a() and b() are as defined in the question
// the following is equivalent to newfunc(x) = b(a(x))
val newFunc: String => String = List( a _, b _).reduce( _ andThen _ )
You can even create a generic function to combine them:
def functionChaining[A]( functions: A => A *): A => A = functions.reduce( _ andThen _ )
or using foldLeft:
def functionChaining[A]( functions: A => A *): A => A = functions.foldLeft( (x:A) => x )( _ andThen _ )
Here is an example of how to use this on the REPL:
scala> val newFunc: String => String = functionChaining( (x:String) => x + "---", (x:String) => x * 4)
scala> newFunc("|")
res12: String = |---|---|---|---
Many answers use andThen, but that will be give you
b(a(s))
Given that you want
a(b(s))
compose is the way to go (well, that or reversing the list, but what's the point?)
def c(s: String) = List[String => String](a, b).reduce(_ compose _)(s)
// or alternatively
def c(s: String) = List(a _, b _).reduce(_ compose _)(s)
As a result
c("foo") // foo,,,...
Now, speaking of what's idiomatic, I believe that
a(b(s))
is more idiomatic and readable than
List(a _, b _).reduce(_ compose _)(s)
This clearly depends on the number of functions you're composing. If you were to have
a(b(c(d(e(f(g(h(s))))))))
then
List[String => String](a, b, c, d, e, f, g, h).reduce(_ compose _)(s)
is probably neater and more idiomatic as well.
If you really think you need to do this:
val c = a _ andThen b
// (The signature is:)
val c:(String)=>String = a _ andThen b
or, more obviously:
def d(s:String) = a _ andThen b
If chained application is preferred then the below works. Caveats - Implicit syntax is a bit ugly; This being a structural type uses reflection.
object string {
implicit def aPimp(s: String) = new {
def a = "(a- " + s + " -a)"
}
implicit def bPimp(s: String) = new {
def b = "(b- " + s + " -b)"
}
}
scala> import string._
scala> "xyz".a.b
res0: String = (b- (a- xyz -a) -b)
scala> "xyz".b.a
res1: String = (a- (b- xyz -b) -a)
In my opinion, if not for the ugly syntax, this would be idiomatic scala.
Related
What is the most concise way to get 10 out of Some(Some(Some(Some(10))))?
without resorting to some external library like Scalaz.
import scala.language.higherKinds
case class Flattener[W[_], WW, T](fn : WW => W[T])
implicit def optionRecFlattenFn[WW, T](
implicit f : Flattener[Option, WW, T] = Flattener((ww: WW) => Option(ww))
) = Flattener((ww : Option[WW]) => ww.flatMap(f.fn))
def optionRecursiveFlatten[WW, T](www : Option[WW])(
implicit f : Flattener[Option, Option[WW], T]
) = f.fn(www)
val nestedOption = Option(Option(Option(Option(10))))
// Some(Some(Some(Some(10))))
val flatOption = optionRecursiveFlatten(nestedOption)
// Some(10)
val evenMoreNestedOption = Option(Option(Option(Option(Option(Option(10))))))
// Some(Some(Some(Some(Some(Some(10))))))
val flatOption2 = optionRecursiveFlatten(evenMoreNestedOption)
// Some(10)
In case you don't know the nesting level in advance, this will work for any level:
def unwrapRec(o: Option[Any]) : Any = o match {
case Some(inner # Some(_)) => unwrapRec(inner)
case Some(x) => x
case _ => ???
}
However, please note that an Any is returned. You can change it to whatever type you like and adapt the pattern match accordingly but I think you will have to pass in an Option[Any]. So it's not typesafe at this point.
You can use flatten on nested Option[Option[A]] repeatedly:
scala> val a = Some(Some(Some(Some(10))))
a: Some[Some[Some[Some[Int]]]] = Some(Some(Some(Some(10))))
scala> a.flatten.flatten.flatten.get
res0: Int = 10
I do not think there is any generic and type-safe way to extract A from T[A] := Option[T[A]] | A.
Edit: This method can dynamically get the contents, returns either the innermost value, or None:
def unwrap(x: Any): Any = x match {
case Some(v) => unwrap(v)
case v => v
}
scala> unwrap(Some(Some(Some(Some(10)))))
res1: Any = 10
scala> unwrap(Some(None))
res2: Any = None
It has unfortunately too broad type: Any => Any.
Slightly simplifying, my problem comes from a list of strings input that I want to parse with a function parse returning Either[String,Int].
Then list.map(parse) returns a list of Eithers. The next step in the program is to format an error message summing up all the errors or passing on the list of parsed integers.
Lets call the solution I'm looking for partitionEithers.
Calling
partitionEithers(List(Left("foo"), Right(1), Left("bar")))
Would give
(List("foo", "bar"),List(1))
Finding something like this in the standard library would be best. Failing that some kind of clean, idiomatic and efficient solution would be best. Also some kind of efficient utility function I could just paste into my projects would be ok.
I was very confused between these 3 earlier questions. As far as I can tell, neither of those questions matches my case, but some answers there seem to contain valid answers to this question.
Scala collections offer a partition function:
val eithers: List[Either[String, Int]] = List(Left("foo"), Right(1), Left("bar"))
eithers.partition(_.isLeft) match {
case (leftList, rightList) =>
(leftList.map(_.left.get), rightList.map(_.right.get))
}
=> res0: (List[String], List[Int]) = (List(foo, bar),List(1))
UPDATE
If you want to wrap it in a (maybe even somewhat type safer) generic function:
def partitionEither[Left : ClassTag, Right : ClassTag](in: List[Either[Left, Right]]): (List[Left], List[Right]) =
in.partition(_.isLeft) match {
case (leftList, rightList) =>
(leftList.collect { case Left(l: Left) => l }, rightList.collect { case Right(r: Right) => r })
}
You could use separate from MonadPlus (scalaz) or MonadCombine (cats) :
import scala.util.{Either, Left, Right}
import scalaz.std.list._
import scalaz.std.either._
import scalaz.syntax.monadPlus._
val l: List[Either[String, Int]] = List(Right(1), Left("error"), Right(2))
l.separate
// (List[String], List[Int]) = (List(error),List(1, 2))
I don't really get the amount of contortions of the other answers. So here is a one liner:
scala> val es:List[Either[Int,String]] =
List(Left(1),Left(2),Right("A"),Right("B"),Left(3),Right("C"))
es: List[Either[Int,String]] = List(Left(1), Left(2), Right(A), Right(B), Left(3), Right(C))
scala> es.foldRight( (List[Int](), List[String]()) ) {
case ( e, (ls, rs) ) => e.fold( l => ( l :: ls, rs), r => ( ls, r :: rs ) )
}
res5: (List[Int], List[String]) = (List(1, 2, 3),List(A, B, C))
Here is an imperative implementation mimicking the style of Scala collection internals.
I wonder if there should something like this in there, since at least I run into this from time to time.
import collection._
import generic._
def partitionEithers[L, R, E, I, CL, CR]
(lrs: I)
(implicit evI: I <:< GenTraversableOnce[E],
evE: E <:< Either[L, R],
cbfl: CanBuildFrom[I, L, CL],
cbfr: CanBuildFrom[I, R, CR])
: (CL, CR) = {
val ls = cbfl()
val rs = cbfr()
ls.sizeHint(lrs.size)
rs.sizeHint(lrs.size)
lrs.foreach { e => evE(e) match {
case Left(l) => ls += l
case Right(r) => rs += r
} }
(ls.result(), rs.result())
}
partitionEithers(List(Left("foo"), Right(1), Left("bar"))) == (List("foo", "bar"), List(1))
partitionEithers(Set(Left("foo"), Right(1), Left("bar"), Right(1))) == (Set("foo", "bar"), Set(1))
You can use foldLeft.
def f(s: Seq[Either[String, Int]]): (Seq[String], Seq[Int]) = {
s.foldRight((Seq[String](), Seq[Int]())) { case (c, r) =>
c match {
case Left(le) => (le +: r._1, r._2)
case Right(ri) => (r._1 , ri +: r._2)
}
}
}
val eithers: List[Either[String, Int]] = List(Left("foo"), Right(1), Left("bar"))
scala> f(eithers)
res0: (Seq[String], Seq[Int]) = (List(foo, bar),List(1))
I'm trying to write some code to make it easy to chain functions that return Scalaz Validation types. One method I am trying to write is analogous to Validation.flatMap (Short circuit that validation) which I will call andPipe. The other is analogous to |#| on ApplicativeBuilder (accumulating errors) except it only returns the final Success type, which I will call andPass
Suppose I have functions:
def allDigits: (String) => ValidationNEL[String, String]
def maxSizeOfTen: (String) => ValidationNEL[String, String]
def toInt: (String) => ValidationNEL[String, Int]
As an example, I would like to first pass the input String to both allDigits and maxSizeOf10. If there are failures, it should short circuit by not calling the toInt function and return either or both failures that occurred. If Successful, I would like to pass the Success value to the toInt function. From there, it would either Succeed with the output value being an Int, or it would fail returning only the validation failure from toInt.
def intInput: (String) => ValidationNEL[String,Int] = (allDigits andPass maxSizeOfTen) andPipe toInt
Is there a way to do this without my add-on implementation below?
Here is my Implementation:
trait ValidationFuncPimp[E,A,B] {
val f: (A) => Validation[E, B]
/** If this validation passes, pass to f2, otherwise fail without accumulating. */
def andPipe[C](f2: (B) => Validation[E,C]): (A) => Validation[E,C] = (a: A) => {
f(a) match {
case Success(x) => f2(x)
case Failure(x) => Failure(x)
}
}
/** Run this validation and the other validation, Success only if both are successful. Fail accumulating errors. */
def andPass[D](f2: (A) => Validation[E,D])(implicit S: Semigroup[E]): (A) => Validation[E,D] = (a:A) => {
(f(a), f2(a)) match {
case (Success(x), Success(y)) => Success(y)
case (Failure(x), Success(y)) => Failure(x)
case (Success(x), Failure(y)) => Failure(y)
case (Failure(x), Failure(y)) => Failure(S.append(x, y))
}
}
}
implicit def toValidationFuncPimp[E,A,B](valFunc : (A) => Validation[E,B]): ValidationFuncPimp[E,A,B] = {
new ValidationFuncPimp[E,A,B] {
val f = valFunc
}
}
I'm not claiming that this answer is necessarily any better than drstevens's, but it takes a slightly different approach and wouldn't fit in a comment there.
First for our validation methods (note that I've changed the type of toInt a bit, for reasons I'll explain below):
import scalaz._, Scalaz._
def allDigits: (String) => ValidationNEL[String, String] =
s => if (s.forall(_.isDigit)) s.successNel else "Not all digits".failNel
def maxSizeOfTen: (String) => ValidationNEL[String, String] =
s => if (s.size <= 10) s.successNel else "Too big".failNel
def toInt(s: String) = try(s.toInt.right) catch {
case _: NumberFormatException => NonEmptyList("Still not an integer").left
}
I'll define a type alias for the sake of convenience:
type ErrorsOr[+A] = NonEmptyList[String] \/ A
Now we've just got a couple of Kleisli arrows:
val validator = Kleisli[ErrorsOr, String, String](
allDigits.flatMap(x => maxSizeOfTen.map(x *> _)) andThen (_.disjunction)
)
val integerizer = Kleisli[ErrorsOr, String, Int](toInt)
Which we can compose:
val together = validator >>> integerizer
And use like this:
scala> together("aaa")
res0: ErrorsOr[Int] = -\/(NonEmptyList(Not all digits))
scala> together("12345678900")
res1: ErrorsOr[Int] = -\/(NonEmptyList(Too big))
scala> together("12345678900a")
res2: ErrorsOr[Int] = -\/(NonEmptyList(Not all digits, Too big))
scala> together("123456789")
res3: ErrorsOr[Int] = \/-(123456789)
Using flatMap on something that isn't monadic makes me a little uncomfortable, and combining our two ValidationNEL methods into a Kleisli arrow in the \/ monad—which also serves as an appropriate model for our string-to-integer conversion—feels a little cleaner to me.
This is relatively concise with little "added code". It is still sort of wonky though because it ignores the successful result of applying allDigits.
scala> val validated = for {
| x <- allDigits
| y <- maxSizeOfTen
| } yield x *> y
validated: String => scalaz.Validation[scalaz.NonEmptyList[String],String] = <function1>
scala> val validatedToInt = (str: String) => validated(str) flatMap(toInt)
validatedToInt: String => scalaz.Validation[scalaz.NonEmptyList[String],Int] = <function1>
scala> validatedToInt("10")
res25: scalaz.Validation[scalaz.NonEmptyList[String],Int] = Success(10)
Alternatively you could keep both of the outputs of allDigits and maxSizeOfTen.
val validated2 = for {
x <- allDigits
y <- maxSizeOfTen
} yield x <|*|> y
I'm curious if someone else could come up with a better way to combine these. It's not really composition...
val validatedToInt = (str: String) => validated2(str) flatMap(_ => toInt(str))
Both validated and validated2 accumulate failures as shown below:
scala> def allDigits: (String) => ValidationNEL[String, String] = _ => failure(NonEmptyList("All Digits Fail"))
allDigits: String => scalaz.Scalaz.ValidationNEL[String,String]
scala> def maxSizeOfTen: (String) => ValidationNEL[String, String] = _ => failure(NonEmptyList("max > 10"))
maxSizeOfTen: String => scalaz.Scalaz.ValidationNEL[String,String]
scala> val validated = for {
| x <- allDigits
| y <- maxSizeOfTen
| } yield x *> y
validated: String => scalaz.Validation[scalaz.NonEmptyList[String],String] = <function1>
scala> val validated2 = for {
| x <- allDigits
| y <- maxSizeOfTen
| } yield x <|*|> y
validated2: String => scalaz.Validation[scalaz.NonEmptyList[String],(String, String)] = <function1>
scala> validated("ten")
res1: scalaz.Validation[scalaz.NonEmptyList[String],String] = Failure(NonEmptyList(All Digits Fail, max > 10))
scala> validated2("ten")
res3: scalaz.Validation[scalaz.NonEmptyList[String],(String, String)] = Failure(NonEmptyList(All Digits Fail, max > 10))
Use ApplicativeBuilder with the first two, so that the errors accumulate,
then flatMap toInt, so toInt only gets called if the first two succeed.
val validInt: String => ValidationNEL[String, Int] =
for {
validStr <- (allDigits |#| maxSizeOfTen)((x,_) => x);
i <- toInt
} yield(i)
Given an example closure, which in this case returns the number of words in a string (with an additional arbitrary operator).
val myfunc = (s: String) => Option(s).map(_.split(" ").size).filter(_ >= 2)
Is there a way I can hide some of the boilerplate such that I can write:
val myfunc = given[String].map(_.split(" ").size).filter(_ >= 2)
If you can live with two parentheses and an underscore extra, you don't need macros for that:
class Given[A] {
def apply[B](f: Option[A] => B): A => B = (a: A) => f(Option(a))
}
def given[A] = new Given[A]
In action:
scala> val myfunc = given[String](_.map(_.split(" ").size).filter(_ >= 2))
myfunc: String => Option[Int] = <function1>
scala> List("salmon cod herring","tuna").map(myfunc)
res4: List[Option[Int]] = List(Some(3), None)
I doubt. A macro replaces the function call it is in with something that type checks. So, what would you replace given[String] with in your example? If you replaced it with (s: String) => Option(s), you'd get this:
((s: String) => Option(s)).map(_.split(" ").size).filter(_ >= 2)
Which doesn't work like you want. You want the whole line to be changed, which is not going to happen.
Let's assume this function:
def autoClosing(f: {def close();})(t: =>Unit) = {
t
f.close()
}
and this snippet:
val a = autoClosing(new X)(_)
a {
println("before close")
}
is it possible to curry the first part? Something like:
val a = autoClosing(_) { println("before close") }
so that I could send the objects on which close should be performed, and have the same block executed on them?
Yes, the snippet you have given works, as long as you give the type of the placeholder character.
Therefore, the code you are looking for is:
val a = autoClosing(_: {def close();}) { println("before close") }
which compiles and works as expected :).
A couple of notes:
You can make your life easier if you define a type alias for an AnyRef type having a close method, something like type Closeable = AnyRef {def close()}, or an appropriate interface.
The code snippet autoClosing(_: Closeable){ ... } is actually equivalent to the following expanded anonymous function: c: Closeable => autoClosing(c){ ... }. The wildcard character is just shorthand for a partially applied function. You need to give the type of the _ as the type inferer unfortunately cannot infer the type in this case.
Hope it helps,
-- Flaviu Cipcigan
Alternatively you can flip the parameters:
def flip[A1, A2, B](f: A1 => A2 => B): A2 => A1 => B = x1 => x2 => f(x2)(x1)
In your case:
val a = flip(autoClosing){ println("before close") }
Edit:
I've added some braces to help the human parser:
def flip[A1, A2, B](f: (A1 => (A2 => B))): (A2 => (A1 => B)) = {
x1 => (x2 => f(x2)(x1))
}
Flip converts a function (A1 => (A2 => B)) to (A2 => (A1 => B)).
scala> def x(x1 : Int)(x2 : Long) = 1.0 * x1 / x2
x: (Int)(Long)Double
scala> val f = flip(x)
f: (Long) => (Int) => Double = <function>
scala> val g = f(1)
g: (Int) => Double = <function>
scala> val h = g(2)
h: Double = 2.0
scala> x(1)(2)
res0: Double = 0.5
I'm happy to see so many people answering Scala questions nowadays. It does make it harder for me to come up with something, however. Here's an alternative to Flaviu's solution.
val a: {def close();} => Unit = autoClosing(_) { println("before close") }
Of course, the proper solution is to define autoClosing in a way compatible with how you are going to use it.