Scala list error - list

After a lot of Java and some Haskell I wanted to have a look at Scala. From the code below, I'm getting this error message
type mismatch; found : List[Nothing] => Option[Nothing] required: List[Int] => Option[Nothing]
I don't know what I'm doing wrong:
object MyFirstScalaObject {
def main(args: Array[String]) {
lazy val testValues:List[List[Int]] = List((1 to 10).toList, null, List());
println( testFunction(last, testValues));
}
def testFunction[I, O](f : I => O, inputs : List[I]):
List[(I, O)] =
inputs.zip(inputs.map(f));
def last[A](xs:List[A]):Option[A] = xs match {
case x::Nil => Some(x);
case _::xs => last(xs);
case _ => None;
}
}
Thanks for any advice.
Cheers,

because of the way type inference works in scala, it is unable to determine the what the type parameter to last has to be, so it has to take the overly conservative fallback guess that it is Nothing.
You can explicitly specify the types when you call testFunction:
testFunction[List[Int],Option[Int](last, testValues)
or you can document more fully the relationship between the type parameters in the testFunction declaration, which will give the type inferencer more information:
def testFunction[A, I[_], O[_]](f : I[A] => O[A], inputs : List[I[A]]): List[(I[A], O[A])]
This explicitly says that I and O are type constructors (kind * -> *), now that the input/output types of f are more specific, the inferencer can correctly infer that the A parameter to the the last function must be Int.

A fully revised & tested version, using senia's idea:
object MyFirstScalaObject {
def main(args: Array[String]) {
lazy val testValues = List((1 to 10).toList, null, List())
println(testFunction(testValues)(last))
}
def testFunction[I, O](inputs: List[I])(f: I => O): List[(I, O)] =
inputs.zip(inputs.map(f))
def last[A](xs: List[A]): Option[A] = xs match {
case x :: Nil => Some(x)
case _ :: xs => last(xs)
case _ => None
}
}
Type inference proceeds left-to-right; information from one parameter list is used within next parameter list.
In this code, when you call testFunction Scala can deduce I from the first parameter, then it can feed I as the input type of the function f to figure out its type (that is, that the argument last is applied with A = Int), then it finally gets the value of O from the return type of the function.

I can't tell you why type inference in scala works this way.
But there is common way to help compiler in such cases - parameter sections.
def testFunction[I, O](inputs : List[I])(f: I => O): List[(I, O)] = inputs.zip(inputs.map(f))
Usage:
testFunction(testValues)(last)
Similar solution is to add method testFunction to class List:
class LastsHelper[T](inputs: List[T]) {
def testFunction[O](f: T => O): List[(T, O)] = inputs.zip(inputs.map(f))
}
implicit def toLastsHelper[T](inputs: List[T]) = new LastsHelper(inputs)
You can use such methods like methods of List:
testValues.testFunction(last)

Related

Basic implementation of a List data structure in Scala

I'm learning Scala and in a book that I'm reading (Functional Programming in Scala) I came across an example of a custom List implementation in Scala which goes like this:
sealed trait MyList[+A]
case object MyNil extends MyList[Nothing]
case class Cons[+A](head: A, tail: MyList[A]) extends MyList[A]
object MyList {
def apply[A](as: A*): MyList[A] =
if (as.isEmpty) MyNil
else Cons(as.head, apply(as. tail: _*))
}
I would like to extend MyList to add the following functionality:
add a tail method that returns all elements of a MyList instance without the first one, e.g. val x = MyList(1,2,3); x.tail == MyList(2,3).
Add a sum method that is only applicable when MyList contains Ints (or even better for all numeric types). So e.g. val x = MyList(1,2,3); x.sum == 6
The idea above 2 questions is to understand: (1) how to interact with the instance of my class and (2) how to use polymorphism in a situation like this. After some searching around, I'm not even sure how to begin with these problems, which is why I'm asking this question.
Any tips would be appreciated. Many thanks!
UPDATE:
A few updates:
First, I'd like to point out that the solution to the programming challenges in the Functional Programming course that I mentioned earlier can be found here, however, I'm looking for something a little different than what the author is asking for.
I've managed to find an answer to my first question "how can I use tail on my instance itself, e.g. MyList(1,2,3).tail?". To solve this, I had to modify the original trait in the following manner:
sealed trait MyList[+A] {
def tail: MyList[A] = MyList.tail(this)
}
I'm not sure if this is the best way of doing what I want to do, but it works. If anyone has better suggestions, please let me know.
The second part is harder. I wanted to add the following inside the same trait:
def sum[Int]: MyList[Int] = MyList.sum(this)
But IntelliJ is complaining about the type of this which is A and I need to apply this conditionally on this being of type Int.
Another alternative is to do the following:
def sum: Int = this match {
case x: MyList[Int] => MyList.sum(x)
}
But what if we want to create another implementation for String that will also return a String? This cannot be the right solution and I haven't found one yet. Please help :)
.tail
I note that your Cons class already has a public tail member. I'd be tempted to start there and just make it universal...
sealed trait MyList[+A] {
def tail: MyList[A]
}
...and add the MyNil implementation.
case object MyNil extends MyList[Nothing] {
def tail: MyList[Nothing] =
throw new java.lang.UnsupportedOperationException("tail of empty list")
}
This is how the standard library List handles the tail of an empty list. Another, perhaps gentler, option would be to return this so that the tail of an empty MyList is just the empty MyList.
Leaving class Cons and object MyList unchanged, we get the expected results.
MyList('s','h','o','w').tail //res0: MyList[Char] = Cons(h,Cons(o,Cons(w,MyNil)))
MyList(9).tail.tail //java.lang.Unsupported...
.sum
This is a bit trickier. We want each .sum invocation to compile only if the elements are of a sum-able type, such as Int. The Scala way to achieve this to require that the call site provide implicit "evidence" that the element type is acceptable.
sealed trait MyList[+A] {
def sum(implicit ev : A =:= Int) : Int //can sum only if A is Int
}
Alas, this won't compile because MyList is covariant on A, but being the type of a passed parameter puts A in a contra-variant position.
Error: covariant type A occurs in invariant position in type A =:= Int of value ev
Fortunately there's a fix for that: use a different type parameter, related to A but not restricted to its covariant relationship.
sealed trait MyList[+A] {
def sum[B >: A](implicit ev : B =:= Int) : Int = 0 //default behavior
}
case object MyNil extends MyList[Nothing] { ... //unchanged
case class Cons[+A](head: A, tail: MyList[A]) extends MyList[A] {
override def sum[B >: A](implicit ev :B =:= Int) : Int = head + tail.sum[B]
}
object MyList { ... //unchanged
MyList(23,31,12).sum //res0: Int = 66
MyList("as","is").sum //won't compile
Numeric[A]
Well that works for Int, but it would be a pain to have to do the same for every sum-able type. Fortunately the standard library offers the Numeric typeclass which provides some basic values (zero and one) and operations (plus(), minus(), times(), etc.) for all the numeric types under its umbrella (Short, Long, Float, etc.).
So, putting it all together:
sealed trait MyList[+A] {
val tail: MyList[A]
def sum[B >: A](implicit ev : Numeric[B]): B = ev.zero
}
case object MyNil extends MyList[Nothing] {
val tail: MyList[Nothing] = this
}
case class Cons[+A](head: A, tail: MyList[A]) extends MyList[A] {
override def sum[B >: A](implicit ev : Numeric[B]): B = ev.plus(head, tail.sum[B])
}
object MyList {
def apply[A](as: A*): MyList[A] =
if (as.isEmpty) MyNil else Cons(as.head, apply(as.tail: _*))
}

How do you handle an exception for a function that returns an unknown type?

Say I have the following type and function:
exception NotFound
type 'a mytype = (string * 'a) list
fun foo [] = raise NotFound
| foo (x, b) :: bs = b
If I were to call the function and pass in an empty list, it will raise an Exception. Normally the function would return b, which is of type 'a. I want to handle the exception but I don't know what type 'a is, so what do I do here?
Related, but I really just want to return a bool. How do I do so?
Obviously the following code does not work as desired but it illustrates what I am trying to accomplish.
fun test mytypeobj = foo mytypeobj handle NotFound => false
(* return true otherwise *)
Your code contains a syntax error because of a left-parenthesis that comes a little too soon:
exception NotFound
type 'a mytype = (string * 'a) list
fun foo [] = raise NotFound
| foo (x, b :: bs) = b
I want to handle the exception but I don't know what type 'a is, so what do I do here?
The exception is unrelated to 'a, so handling it is a matter of:
val bar = foo [] handle NotFound => ...
I really just want to return a bool. How do I do so?
fun test mytypeobj = foo mytypeobj handle NotFound => false (* otherwise true *)
Since the function foo demonstrates no practical purpose, I am unsure what boolean you want to return. If you don't care if the boolean you're returning is the result of computing foo ..., you can do the following to discard the result and return a boolean of your choice:
fun test bs = (foo bs; true) handle NotFound => false
If b::bs is a list of booleans and you want to return the first of those, then that's what your function does. You can't be sure, of course, that it's true. The pattern I just mentioned is useful for unit testing when a function is throwing the right message. You could for example test that hd on the empty list correctly throws Empty:
fun test_hd_empty = (hd []; false) handle Empty => true
| _ => false
This test says that if hd [] doesn't throw, its result is discarded and the test fails. And if it does throw, but the exception isn't Empty, it should also fail.

Akka Streams Graph DSL notation

I used graph dsl to create some stream processing jobs based on some example code I saw. Everything runs great, I am just having trouble understanding the notation: (updated for 2.4)
def elements: Source[Foos] = ...
def logEveryNSink = // a sink that logs
def cleaner: Flow[Foos, Bars, Unit] = ...
def boolChecker(bar: Bar)(implicit ex: ExecutionContext): Future[Boolean] = ...
val mySink = Sink.foreach[Boolean](println(_))
val lastly = Flow[Bars].mapAsync(2)(x => boolChecker(x).toMat(mySink)(Keep.right)
val materialized = RunnableGraph.fromGraph(
GraphDSL.create(lastly) { implicit builder =>
baz => {
import GraphDSL.Implicits._
val broadcast1 = builder.add(Broadcast[Foos](2))
val broadcast2 = builder.add(Broadcast[Bars](2))
elements ~> broadcast1 ~> logEveryNSink(1)
broadcast1 ~> cleaner ~> broadcast2 ~> baz
~> broadcast2 ~> logEveryNSink(1)
ClosedShape
}
}
).run()
I understand the implicit builder that is included, but Im uncertain what the baz represents in { implicit builder => baz => { .... is it just an implicit name for the entire shape?
The GraphDSL.create method is heavily overloaded to take in many variants of amounts of input shapes (including 0). If you pass in no initial shapes, then the signature of the buildBlock function arg (the body where you actually define how the graph is to be built) is as follows:
(Builder[NotUsed]) => S
So this is simply a Function1[Builder[NotUsed], S], that is, a function that takes an instance of a Builder[NotUsed] and returns a Shape instance which is the final graph. The NotUsed here is synonymous with Unit in that you are saying that by not passing in any input shares that you do not care about the materialized value of the output graph being produced.
If you do decide to pass in input shapes, then the signature of that buildBlock function changes a bit to accomadate the input shapes. In your case, you are passing in 1 input shape, so the signature of buildBlock changes to:
(Builder[Mat]) => Graph.Shape => S
Now, this is essentially a Function1[Builder[Mat], Function1[Graph.Shape, S]], or a function that takes a Builder[Mat] (where Mat is the materialized value type of the input shape) and returns a function that takes a Graph.Shape and returns an instance of S (which is a Shape).
Long story short, if you pass in shapes, then you also need to declare them as bound params on the graph building block function but as a second input function (hence the additional =>).

type mismatch error declaring list of classes

def getValueAndItsType() : List[ (AnyRef, Class[_]) ] = {
val dataSet1 = ("some string data", classOf[String])
val dataSet2 = (new Thread(), classOf[Thread])
val dataSet3 = (new NullPointerException(), classOf[NullPointerException])
val dataSet4 = (5, classOf[Int])
val list = List(dataSet1, dataSet2, dataSet3, dataSet4)
list
}
Type type mismatch; found :
List[(Any, Class[_ >: Int with NullPointerException with Thread with
String])] required: List[(AnyRef, Class[_])]
If dataSet4 is removed from List, the compile time error disappears
Please suggest, what is wrong with Class[_]. Isn't it
equivalent to Class[?] in java ? I appreciate, if you also suggest
correct declaration for doing this..
In Scala:
Any is the root of the Scala class.
AnyRef is the root of the class of reference types, it extends from Any.
AnyVal is the root class of all value types. it extends from Any
Null is a subtype of all reference types.
Nothingis a subtype of all other types including Null
So base on your code, you need to extend from Any, include AnyRef: reference types and AnyVal: values types.
def getValueAndItsType() : List[ (Any, _ <: Any) ] = {
val dataSet1 = ("some string data", classOf[String])
val dataSet2 = (new Thread(), classOf[Thread])
val dataSet3 = (new NullPointerException(), classOf[NullPointerException])
val list = List(dataSet1, dataSet2, dataSet3)
list
}

Call collect on partial function as member of an object

I am using some functions that return Options, but I would like to replace them by PartialFunctions in order to use the collect function in Scala. In detail I am trying to call collect (and collectFirst) on a list of objects that contain a partial function in the following way:
class A(val bs : List[B]) {
def getAll(i : Int): List[Int] = bs.map(_.foo(i))
}
class B(val y : Int) {
val foo : PartialFunction[Int, Int] = {
case x if x > y => y
}
}
The above code compiles and does what I want to if the function foo is defined for all values in bs.
val a = new A(List(new B(1), new B(2), new B(3)));
println(a.getAll(5))
prints "List(1, 2, 3)", but of course I run into an error if foo is not defined for a value. Hence, I want to replace it by "collect"
def getAll(i : Int): List[Int] = bs.collect(_.foo(i))
In my understanding collect should work pretty much the same as map, yet still the above code does not compile (I get a type mismatch because foo cannot be resolved). What is the best way in this case?
collect expects to receive a partial function (not a function or lambda), that will take an element of your collection as an input: PartialFunction[B, Int]. But here you want just to call your PartialFunction[Int, Int] inside another function, so you don't even passing a PartialFunction into collect (you're passing function (_.foo(i)): B => Int).
Solution without collect (but still with PartialFunction as a member of B):
def getAll(i : Int): List[Int] = bs.flatMap(_.foo.lift(i))
lift rises your function from PartialFunction[Int, Int] to Int => Option[Int] here.
If you really really want to collect:
import Function._
def getAll(i : Int): List[Int] = bs.collect(unlift(_.foo.lift(i)))
unlift reduces B => Option[Int] into PartialFunction[B, Int]
The ugliest version is collect{ case x if x.foo.isDefinedAt(i) => x.foo(i) }
Better solution is to move your partial function outside of B:
case class A(bs : List[B]) {
def getAll(x : Int): List[Int] = bs.collect {
case B(y) if x > y => y
}
}
case class B(val y : Int)