Found error on using list in scala - scala

I am using Scala for studying purpose
I wrote this code to sort the elements in list
def isort(xs:List[Int]):List[Int]=
xs match{
case List() => xs
case y::ys => insert(y,isort(ys))
}
def insert(x:Int,xs:List[Int]):List[Int]=
xs match{
case List() => List(x)
case y::ys => if(x<y) x::xs else y :: insert(x,ys)
}
but I am getting the following error:
Constructor can not be instantiated to expected type found Scala.collection.Immutable required List[Int]
in
`y::ys => insert(y,isort(ys))`
and similar error where I use ::
I refer tutorial : https://class.coursera.org/progfun-005/lecture

Try using the paste mode of the REPL. This will allow you to define the two defs in the same context:
scala> :paste
// Entering paste mode (ctrl-D to finish)
def isort(xs:List[Int]):List[Int]=
xs match{
case List() => xs
case y::ys => insert(y,isort(ys))
}
def insert(x:Int,xs:List[Int]):List[Int]=
xs match{
case List() => List(x)
case y::ys => if(x<y) x::xs else y :: insert(x,ys)
}
// Exiting paste mode, now interpreting.
isort: (xs: List[Int])List[Int]
insert: (x: Int, xs: List[Int])List[Int]

Related

No implicit Ordering Defined on Pattern Matched List

On Scala 2.11.8:
private def safeMax[A](xs: List[A])
(implicit ev: Ordering[A]): Option[A] = xs match {
case ys#(_ :: _) => Some(ys.min)
case Nil => None
}
// Exiting paste mode, now interpreting.
<console>:12: error: No implicit Ordering defined for ?A1.
case ys#(_ :: _) => Some(ys.min)
^
Since ys has type List[A], as I understand, then why does this compile-time error occur?
Note that I could fix it by replace ys.min with xs.min, but I'm still curious.

Scala Pattern match on a list with at `#` symbol an extractor

I would like to access a reference of the first element
List(Some(1), None) match {
case x#Some(1) :: xs => x
case _ => None
}
res0: java.io.Serializable = List(Some(1), None)
The pattern matches correctly.
However I expected x to be the Some(1), that is the head of the list, and NOT the list itself.
How can I both use the extractors AND have a reference to the element?
I made it work just wrapping the element in parentheses
val lst = List(Option(1), None)
lst match {
case (x#Some(1)) :: xs => x
case _ => None
}
res0: Option[Int] = Some(1)
And it works also for multiple extractors!
val lst = List(Option(1),Option(2), None)
lst match {
case (x#Some(1)) :: (y#Some(2)) :: xs => y
case _ => None
}

Idiomatic scala for getting a single option out of two Options and throwing exception if two are available

val one: Option[Int] = None
val two = Some(2)
Option(one.getOrElse(two.getOrElse(null))) // Gives me Some(2) which I want
val one = Some(1)
val two = None
Option(one.getOrElse(two.getOrElse(null))) // Gives me Some(1) which I want
val one: Option[Int] = None
val two: Option[Int] = None
Option(one.getOrElse(two.getOrElse(null))) // Gives me None which I want
val one = Some(1)
val two = Some(2)
Option(one.getOrElse(two.getOrElse(null))) // Gives me Some(1) when I want an exception
I briefly looked into the Either type but it seems like it is for "Representing a value of one of two possible types". Am I missing some data structure or Monad? Essentially I want a explicit (and error throwing if both are valuable) get either one if it avaiable or get None
I don't know any pre built to do that, so here is a function:
def xor[T](x: Option[T], y: Option[T]): Option[T] = (x, y) match {
case (Some(_), None) => x
case (None, Some(_)) => y
case (None, None) => None
case _ => throw new Exception()
}
Here's my version of the function
val options = Seq(one, two).flatten
if (options.size > 1) throw new Exception("two options were provided")
options.headOption
def xor[T](a: Option[T], b: Option[T]) =
a orElse b ensuring (_ => a zip b isEmpty)
I would probably go old school if-else for the simple case.
scala> implicit class optxor[A](val opt: Option[A]) extends AnyVal {
| def xor(other: Option[A]) = if (opt.isEmpty) other else if (other.isEmpty) opt else ??? }
defined class optxor
scala> one xor two
res18: Option[Int] = Some(2)
scala> two xor three
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225)
at optxor$.xor$extension(<console>:8)
... 33 elided
I would have approached this using a pattern matching function like gzou answered, but here's a one liner:
one.map{x => two.foreach(y => throw new Exception("both defined")); x}.orElse(two)
We can combine the 2 Options as an Iterable with Option's ++ operator, and thus pattern match on iterables instead of tuple of options:
optionA ++ optionB match {
case Seq(x, y) => throw new Exception
case x => x.headOption
}
// None and None => None
// Some(5) and None => Some(5)
// None and Some(5) => Some(5)
// Some(5) and Some(3) => Exception
Note headOption which nicely handles both the list with 1 element and the empty list.
Or,
scala> val one: Option[Int] = None
one: Option[Int] = None
scala> val two = Option(2)
two: Option[Int] = Some(2)
scala> val three = Option(3)
three: Option[Int] = Some(3)
scala> (for (_ <- one; _ <- two) yield ???) orElse one orElse two
res0: Option[Int] = Some(2)
scala> (for (_ <- three; _ <- two) yield ???) orElse three orElse two
scala.NotImplementedError: an implementation is missing
at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225)
at $anonfun$1$$anonfun$apply$1.apply(<console>:10)
at $anonfun$1$$anonfun$apply$1.apply(<console>:10)
at scala.Option.map(Option.scala:145)
at $anonfun$1.apply(<console>:10)
at $anonfun$1.apply(<console>:10)
at scala.Option.flatMap(Option.scala:170)
... 33 elided
desugaring to
scala> one flatMap (_ => two) map (_ => ???) orElse one orElse two
res3: Option[Int] = Some(2)
but idiomatically it's hard to imagine doing either of these.
How about this?
import scala.util.Try
object XorOption {
def xorOptions[T](one: Option[T], two: Option[T]): Try[Option[T]] = {
Try {
for (x <- one; y <- two) throw new RuntimeException
one.orElse(two)
}
}
def main(args: Array[String]) {
val testData = List(
(None, None),
(None, Some(2)),
(Some(1), None),
(Some(1), Some(2)))
for (t <- testData) {
println(t + " => " + xorOptions(t._1, t._2))
}
}
}
Output:
(None,None) => Success(None)
(None,Some(2)) => Success(Some(2))
(Some(1),None) => Success(Some(1))
(Some(1),Some(2)) => Failure(java.lang.RuntimeException)
List(Some(1), Some(2)).flatten match {
case x :: Nil => Some(x)
case Nil => None
case _ => throw new Exception
}

Scala: Using a TypeTag to match on a Some's type

See the following code:
def createOption[T: TypeTag](referentialData: Any) : Option[T] = {
Option(referentialData) match {
case Some(camelMessage: CamelMessage) => {
Option(camelMessage.body) match {
case Some(option: T) => Some(option)
case _ => None
}
}
case _ => None
}
}
Basically I am looking to return an Option[T] if camelMessage.body is non-null and of type T.
The uses of Option(referentialData) is effectively referentialData != null
Likewise for Option(camelMessage.body)
How do I use the TypeTag to determine if camelMessage.body is of type T.
(I know this can be re-written to not use TypeTags and Options but I want to learn how to use TypeTags so please no suggestions to re-write, thanks!)
Edit
I tried a new approach as could not find a solution for the above, but could not get this one to work either:
def createOption[T](referentialData: Any) : Option[T] = {
Option(referentialData) match {
case Some(option) => Try(option.asInstanceOf[T]).toOption
case _ => None
}
}
When I invoke this using createOption[Long]("test") I was presuming to get a None back, but instead I got a Some(String)
Where am I going wrong here?
This is a duplicate of this one.
But you want to try it with ClassTag to show the limitation:
scala> def f[A: ClassTag](x: Any): Option[A] = x match {
| case y: A => println("OK"); Some(y) ; case _ => println("Nope"); None }
f: [A](x: Any)(implicit evidence$1: scala.reflect.ClassTag[A])Option[A]
scala> f[String]("foo")
OK
res0: Option[String] = Some(foo)
scala> f[Long](2L)
Nope
res1: Option[Long] = None
scala> f[java.lang.Long](new java.lang.Long(2L))
OK
res2: Option[Long] = Some(2)
scala> def f[A: TypeTag](x: Any): Option[A] = Option(x) match {
| case Some(y: A) => println("OK"); Some(y) ; case _ => println("Nope"); None }
<console>:51: warning: abstract type pattern A is unchecked since it is eliminated by erasure
case Some(y: A) => println("OK"); Some(y) ; case _ => println("Nope"); None }
^
f: [A](x: Any)(implicit evidence$1: reflect.runtime.universe.TypeTag[A])Option[A]

Scala's Implementation of haskell last method

I am trying to do some examples programs in scala to get more familiar with the language, For that I am trying to re-implement some of the built in methods in Haskell, Most of these methods I am sure are also implemented in Scala too, But these are just for my practice. I think I can post some of code snippets (not all of them) to get a better way of doing things and to validate my understanding of scala. So please let me know if this is not the place to do these things.
Here is my scala implementation to get the last element of any list. Is this the right way of doing things, By using Any am I loosing the type of the object containing in the list? Is this how this kind of things implemented in scala?
def getLast(xs: List[Any]): Any = xs match {
case List() => null
case x :: List() => x
case _ :: ys => getLast(ys)
}
Parameterize the type of your function and use "Nil" instead of List() like so:
def getLast[T](xs: List[T]): T = xs match {
case Nil => null.asInstanceOf[T]
case x :: Nil => x
case _ :: ys => getLast(ys)
}
Also, consider making it return an Option type:
def getLast[T](xs: List[T]): Option[T] = xs match {
case Nil => None
case x :: Nil => Some(x)
case _ :: ys => getLast(ys)
}
Usage:
val listOfInts = List(1,2,3)
assert(getLast(listOfInts).isInstanceOf[Int])
val listOfStrings = List("one","two","three")
assert(getLast(listOfStrings).isInstanceOf[String])
Firstly, avoid the null, and especially null.asInstanceOf[T]. Observe the danger with primitives:
scala> null.asInstanceOf[Int]
res19: Int = 0
scala> null.asInstanceOf[Boolean]
res20: Boolean = false
So the signature should either be List[T] => T, whereby last on an empty iterator throws an exception:
def last[T](ts: List[T]): T = ts match {
case Nil => throw new NoSuchElementException
case t :: Nil => t
case t :: ts => last(ts)
}
Or instead: List[T] => Option[T]
def lastOption[T](ts: List[T]): Option[T] = ts match {
case Nil => None
case t :: Nil => Some(t)
case t :: ts => lastOption(ts)
}
def lastOption1[T](ts: List[T]): Option[T] = ts.reverse.headOption
def lastOptionInScala28[T](ts: List[T]): Option[T] = ts.lastOption // :)