Scala extending the List class with a coalesce preappend method - list

Im attempting to create a new operator :? on lists, which operates the same as :: except if the value if null, then the original list is returned. I have written the following, however it soon dawned that I didn't really know what I was doing....
object ImplicitList {
implicit def extendIterator[T](i : List[T]) = new ListExtension(i)
}
class ListExtension[T <: Any](i : List[T]) {
def :?[B >: T] (x: B): List[B] = if (x != null) x :: i else i
}
final case class :?[B](private val hd: B, private val tl: ListExtension[B]) extends ListExtension[B](tl.:?(hd))

What you want is the enhance-my-library pattern. With this you can add a new method to List. Here's how that would look:
class EnhancedList[T](self: List[T]) {
def ?:(t: T) =
t match {
case null => self
case _ => t :: self
}
}
implicit def enhanceList[T](self: List[T]) = new EnhancedList(self)
So there's a class EnhancedList that wraps List where the new method ?: is defined, and an implicit function that converts List to EnhancedList when ?: is called. Note that you have to use ?: instead of :? because Scala's rules are such that an operator is right-associative if and only if it ends in a :.
Here's how it gets used:
scala> val l = List("a","b","c")
l: List[java.lang.String] = List(a, b, c)
scala> null ?: l
res136: List[java.lang.String] = List(a, b, c)
scala> "d" ?: l
res137: List[java.lang.String] = List(d, a, b, c)

Related

In a function in won't compile but outside it will

def combinations(list: List[(Char, Int)]) : List[List[(Char,Int)]]= {
val t = List.range(0, 1)
list match {
case List() => List()
case (c,i) :: xs => val res = for {
o <- List.range(1, i + 1)
} yield List((c, o)) :: combinations(xs)
List()
}
}
I have the following function which won't compile if I try to return res instead of List(). It's a type mismatch of List(List(List[(Char,Int)]]] However this code:
List(('a',10)) :: combinations(List())
compiles perfectly and as expected. Why is it that inside the function it won't compile? Isn't it the exact same thing? How could I tackle this?
Your for-comprehension yields an element of type List[List[(Char,Int)]].
For-comprehensions will generate lists of the elements they're yielding, so in this case that will be a List[List[List[(Char,Int)]]].
I'm not entirely sure what you're trying to achieve, but I think it'll be something like this:
def combinations(list: List[(Char, Int)]) : List[List[(Char,Int)]]= {
val t = List.range(0, 1)
list match {
case Nil => List()
case (c,i) :: xs =>
(for {
o <- List.range(1, i + 1)
} yield (c, o)) :: combinations(xs)
}
}
The for-comprehension generates a List[(Char, Int)] which is added at the head of the list generated by your combinations method.

How to extend a Scala list to enable slicing not by explicit position but by given predicate/condition

For
trait Item
case class TypeA(i: Int) extends Item
case class TypeB(i: Int) extends Item
consider a Scala list of items such as
val myList = List(TypeA(1), TypeB(11), TypeB(12),
TypeA(2), TypeB(21),
TypeA(3), TypeB(31))
The goal is to define a new slice method that can be applied onto myList and which takes a predicate or condition as argument; for instance
myList.slice { x => x.isInstanceOf[TypeA] }
would deliver
List(List(TypeA(1), TypeB(11), TypeB(12)),
List(TypeA(2), TypeB(21)),
List(TypeA(3), TypeB(31)))
In this example, an identical result would be achieved by
myList.slice { case TypeA(x) => x < 10 }
Many Thanks.
List already has a slice method - it takes a subset of elements between a start and end index. What you're looking for is repeated application of the span method:
def span(p: (A) ⇒ Boolean): (List[A], List[A])
Which is documented as:
Splits this list into a prefix/suffix pair according to a predicate.
Note: c span p is equivalent to (but possibly more efficient than) (c takeWhile p, c dropWhile p), provided the evaluation of the predicate p does not cause any side-effects.
returns: a pair consisting of the longest prefix of this list whose elements all satisfy p, and the rest of this list.
You can get what you need by repeatedly using this method with an inverse predicate, and an extra bit of logic to ensure that none of the returned Lists are empty.
import annotation.tailrec
def multiSpan[A](xs: List[A])(splitOn: (A) => Boolean): List[List[A]] = {
#tailrec
def loop(xs: List[A], acc: List[List[A]]) : List[List[A]] = xs match {
case Nil => acc
case x :: Nil => List(x) :: acc
case h :: t =>
val (pre,post) = t.span(!splitOn(_))
loop(post, (h :: pre) :: acc)
}
loop(xs, Nil).reverse
}
UPDATE
As requested in comments on the original post, here's a version that enriches list instead of being a standalone method:
implicit class AddMultispanToList[A](val list: List[A]) extends AnyVal {
def multiSpan(splitOn: (A) => Boolean): List[List[A]] = {
#tailrec
def loop(xs: List[A], acc: List[List[A]]) : List[List[A]] = xs match {
case Nil => acc
case x :: Nil => List(x) :: acc
case h :: t =>
val (pre,post) = t.span(!splitOn(_))
loop(post, (h :: pre) :: acc)
}
loop(list, Nil).reverse
}
}
Use as:
myList.multiSpan(_.isInstanceOf[TypeA])
Why couldn't you use partition method from the standard API?
example:
scala> val l = List(3,5,4,6)
l: List[Int] = List(3, 5, 4, 6)
scala>
scala> val (odd,even) = l.partition(_ %2 ==1)
odd: List[Int] = List(3, 5)
even: List[Int] = List(4, 6)
For your example:
scala> val (typeA,typeB) = myList.partition(_.isInstanceOf[TypeA])
typeA: List[Product with Serializable with Item] = List(TypeA(1), TypeA(2), TypeA(3))
typeB: List[Product with Serializable with Item] = List(TypeB(11), TypeB(12), TypeB(21), TypeB(31))
Aren't you looking for filter, which works (almost) without any tweaks for your examples?
$ sbt console
scala> trait Item
scala> case class TypeA(i: Int) extends Item
scala> case class TypeB(i: Int) extends Item
scala> val myList = List(TypeA(1), TypeB(11), TypeB(12),
TypeA(2), TypeB(21),
TypeA(3), TypeB(31))
myList: List[Product with Serializable with Item] = List(TypeA(1), TypeB(11), TypeB(12), TypeA(2), TypeB(21), TypeA(3), TypeB(31))
your first works unaltered:
scala> myList.filter { x => x.isInstanceOf[TypeA] }
res0: List[Product with Serializable with Item] = List(TypeA(1), TypeA(2), TypeA(3))
your second requires a default case:
scala> myList.filter { case TypeA(x) => x < 10; case _ => false }
res2: List[Product with Serializable with Item] = List(TypeA(1(3))
See also collect, which takes a partial function instead of a boolean predicate:
scala> myList.collect { case z # TypeA(x) if x < 10 => z }
res3: List[TypeA] = List(TypeA(1), TypeA(2), TypeA(3))
and can transform as well:
scala> myList.collect { case TypeA(x) if x < 10 => x }
res4: List[Int] = List(1, 2, 3)

Filter usage in shapeless, Scala

It is easy to filter HList in shapeless by type:
val hlist = 1 :: 2 :: "3" :: true :: false :: HNil
hlist.filter[Int]
But how can I make my custom type filter? I want smth like that: for example I got list of some functions:
def function1(s: String) = s.toInt
def function2(s: String) = s.toDouble
def function3(i: Int) = i.toDouble
val hflist = function1 _ :: function3 _ :: function2 _ :: HNil
hflist customFilter[String] //> function1 _ :: function2 _ :: HNil
So after usage of this filter, list of functions from type String to some other type will be constructed.
I had an idea to use map for this, but it was not successfull.
EDITION
More information about my comment:
I tried to test this ideas in map:
So if i got some lists (lets operate with hlist & hflist):
object allFunction extends Poly1 {
implicit def default[T, M] =
at[T => M](t => {
object grabStringFunc extends skip {
implicit def stringFunc[A] = at[T => A](_ :: HNil)
}
println(hflist flatMap grabStringFunc) //> here we should see result, list of functions
})
hlist map allFunction
//> result of this should be smth like (types)
//> shapeless.::[Int => Double,shapeless.HNil]]
//> shapeless.::[Int => Double,shapeless.HNil]]
//> shapeless.::[String => Int,shapeless.::[String => Double,shapeless.HNil]]
//> shapeless.HNil
//> shapeless.HNil
Very interesting, why it compiles and works incorrect? As I think it is not works, cause object cant take type prameters in such a way...
The easiest way is to use a fold. First we need a polymorphic function that will add each item to the accumulator if it has the desired type (String => A for some A), and ignore it otherwise:
trait ignore extends Poly2 {
implicit def default[A, L <: HList] = at[A, L]((_, l) => l)
}
object keepStringFunc extends ignore {
implicit def stringFunc[A, L <: HList] = at[String => A, L](_ :: _)
}
Now the following will give the result you want in both 1.2.4 and 2.0.0-M1:
val filtered = hflist.foldRight(HNil)(keepStringFunc)
You could also write your own type class on the model of Filter, FilterAux (or Filter.Aux), etc.—and doing so would be a good exercise if you're trying to get the hang of Shapeless—but foldRight is a lot simpler.
Update: actually, for what it's worth, there's a slightly more concise way to do this with flatMap:
trait skip extends Poly1 {
implicit def default[A] = at[A](_ => HNil)
}
object grabStringFunc extends skip {
implicit def stringFunc[A] = at[String => A](_ :: HNil)
}
val filtered = hflist flatMap grabStringFunc
I personally find the foldRight version a little more obvious, but this one's also pretty elegant.
In response to your comment: you can make the solution a little more generic like this:
trait skip extends Poly1 {
implicit def default[A] = at[A](_ => HNil)
}
trait grabFuncFrom[T] extends skip {
implicit def stringFunc[A] = at[T => A](_ :: HNil)
}
object grabStringFunc extends grabFuncFrom[String]
val filtered = hflist flatMap grabStringFunc
But you're still going to need that last step where you create the higher rank function as an object (see e.g. this answer and Miles's comment there for some discussion of this issue).

Deep-reverse of nested lists in Scala

I'd like to reverse a list of lists, recursively, in Scala.
I've written deep list reverses in Python like this:
def deepReverse(items):
if type(items) == list:
return [deepReverse(item) for item in reversed(items)]
else:
return items
How would I do the equivalent in Scala? The problem isn't the algorithm - it's the type stuff, which I'm newer on.
I need the function to take a list of [T], or a List[List[T]], or a list of T's and lists of Ts, to any arbitrary depth. I tried making a case class to do that based on an example I'd seen elsewhere. I don't want a function that just returns Any and accepts Any; that feels like cheating.
case class NL[+T](val v : Either[List[NL[T]],T])
Still, I couldn't quite get my types to balance out. I'm new to Scala, but I figured it'd be a perfect opportunity to mess with recursion and typing.
It's actually not too hard to write a version of the type class approach that sschaef proposes that will work for arbitrarily nested lists:
trait Reverser[C] {
def reverse(xs: C): C
}
implicit def rev[A](implicit ev: Reverser[A] = null) = new Reverser[List[A]] {
def reverse(xs: List[A]) =
Option(ev).map(r => xs map r.reverse).getOrElse(xs).reverse
}
def deepReverse[A](xs: A)(implicit ev: Reverser[A]): A = ev.reverse(xs)
The implicit argument ev in our rev method is evidence that A itself is reversable, and if ev is null that means it's not. If we have this evidence that A is reversable, we use it to reverse the elements of our List[A] (this is what the map is doing), and then we reverse the list itself. If we don't have this evidence (the getOrElse case), we can just reverse the list.
We could write rev a little less concisely (but possibly more performantly) like this:
implicit def rev[A](implicit ev: Reverser[A] = null) = if (ev == null) {
new Reverser[List[A]] {
def reverse(xs: List[A]) = xs.reverse
}
} else {
new Reverser[List[A]] {
def reverse(xs: List[A]) = (xs map ev.reverse).reverse
}
}
To test either of these two versions, we can write the following:
scala> deepReverse(List.tabulate(3)(identity))
res0: List[Int] = List(2, 1, 0)
scala> deepReverse(List.tabulate(2,3) { case (a, b) => a + b })
res1: List[List[Int]] = List(List(3, 2, 1), List(2, 1, 0))
scala> deepReverse(List.tabulate(2, 3, 4, 5, 6) {
| case (a, b, c, d, e) => a + b + c + d + e
| }).head.head.head.head
res2: List[Int] = List(15, 14, 13, 12, 11, 10)
As expected.
I should add that the following is a more common idiom for getting the implicits right in a case like this:
trait ReverserLow {
implicit def listReverser[A] = new Reverser[List[A]] {
def reverse(xs: List[A]) = xs.reverse
}
}
object ReverserHigh extends ReverserLow {
implicit def nestedListReverser[A](implicit ev: Reverser[A]) =
new Reverser[List[A]] {
def reverse(xs: List[A]) = xs.map(ev.reverse).reverse
}
}
import ReverserHigh._
If we'd just written listReverser and nestedListReverser at the same level, we'd get the following error when we try to reverse a list of lists:
scala> deepReverse(List.tabulate(2, 3)(_ + _))
<console>:12: error: ambiguous implicit values:
both method listReverser...
and method nestedListReverser...
match expected type Reverser[List[List[Int]]]
deepReverse(List.tabulate(2, 3)(_ + _))
The standard approach to prioritizing the two is to put the lower priority implicit in a trait (WhateverLow) and the other in an object (WhateverHigh) that extends that trait. In a fairly simple case like this, though, it's more concise (and clearer, to my eye) to use the default argument trick in my rev method above. But you're more likely to see the other version in other people's code.
If you wanna have this really typesafe then the typeclass pattern is your friend:
object Reverse extends App {
trait Reverser[C] {
def reverse(xs: C): C
}
implicit def List1Reverser[A] = new Reverser[List[A]] {
def reverse(xs: List[A]) =
xs.reverse
}
implicit def List2Reverser[A] = new Reverser[List[List[A]]] {
def reverse(xs: List[List[A]]) =
xs.map(_.reverse).reverse
}
implicit def List3Reverser[A] = new Reverser[List[List[List[A]]]] {
def reverse(xs: List[List[List[A]]]) =
xs.map(_.map(_.reverse).reverse).reverse
}
def deepReverse[A](xs: A)(implicit rev: Reverser[A]): A =
rev.reverse(xs)
val xs = List(1,2)
val xxs = List(List(1,2),List(1,2),List(1,2))
val xxxs = List(List(List(1,2),List(1,2)),List(List(1,2),List(1,2)),List(List(1,2),List(1,2)))
println(deepReverse(xs))
println(deepReverse(xxs))
println(deepReverse(xxxs))
}
The only problem with this is that you need a typeclass for each nested list type.

scala zip list to tuple

Working with JodaTime, trying to convert a List[LocalDate] to Tuple2[JodaTime, JodaTime] so I can do multi-assigment like so:
val(expire, now) =
List(row.expireDate, new JodaDate) zip (_.toDateTimeAtStartOfDay.getMillis)
which of course does not compile. Is there a similarly concise way to do the above? I know I can just do it manually:
val(expire, now) =
(row.expireDate.toDateTimeAtStartOfDay.getMillis,
new JodaDate().toDateTimeAtStartOfDay.getMillis)
but that's a bit ugly
val Seq(expire, now) =
Seq(row.expireDate, new JodaDate).map(_.toDateTimeAtStartOfDay.getMillis)
What you want (assuming you don't want to go the conversion-to-Seq route) is Scalaz's Bifunctor instance for tuples (which isn't in the standard library). With it you can write the following:
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> val cap = (_: String).toUpperCase
cap: String => java.lang.String = <function1>
scala> val removeLs = (_: String).replaceAll("l", "")
removeLs: String => java.lang.String = <function1>
scala> cap <-: ("hello", "world") :-> removeLs
res0: (java.lang.String, java.lang.String) = (HELLO,word)
Or, in your case:
val f = (_: JodaDate).toDateTimeAtStartOfDay.getMillis
val (expire, now) = f <-: (row.expireDate, new JodaDate) :-> f
val Seq(a, b) =
Seq("a", "b").map(_.toUpperCase)
println("a, b = %s, %s".format(a, b)) // a, b = A, B
If you want to keep the type safety of using a tuple (remember, when unapplying a Seq, the compiler will not check the length), you can write a wrapper to add a function not available in the standard library, which will let you map over a tuple.
In the case of mapping over both elements using a single function, because a Tuple2[A, B] has two type parameters, the key to making this work is to require evidence that A and B are the same type. To do this, require an implicit parameter of type B =:= A; if the types are indeed equal, the compiler will supply a function of type B => A.
class Tuple2Wrapper[A, B](t: (A, B)) {
def bimap[C, D](f: A => C, g: B => D): (C, D) = (f(t._1), g(t._2))
def <-:->[C](f: A => C)(implicit ev: B =:= A): (C, C) = bimap(f, f compose ev)
}
implicit def tuple2Tuple2Wrapper[A, B](t: (A, B)) = new Tuple2Wrapper(t)
scala> (1, 1) <-:-> (_ + 1)
res1: (Int, Int) = (2,2)
This could be done in a more general and useful way (applicable to more types than just Tuple2), if implemented in terms of Scalaz's Bifunctor trait.