"Constructor cannot be instantiated to expected type" when defining streams in Scala - scala

I tried to implement a StreamInt (without using generic types) and got an error message from REPL
<console>:29: error: constructor cannot be instantiated to expected type;
found : Cons
required: StreamInt.type
case Cons(hd,tl)=> if (n==0) hd else tl().nth(n-1)
The code is pasted below. Anyone can show me how to get it right?
trait StreamInt
case object Empty extends StreamInt
case class Cons (hd: Int, tl: ()=>StreamInt) extends StreamInt
object StreamInt{
def cons(hd:Int, tl: => StreamInt):StreamInt = {
val head=hd
lazy val tail=tl
Cons(head, ()=>tail)
}
def empty:StreamInt = Empty
def apply(as: Int*):StreamInt={
if (as.isEmpty) empty
else cons(as.head, apply(as.tail: _*))
}
def nth(n:Int):Int= this match {
case Cons(hd,tl)=> if (n==0) hd else tl().nth(n-1)
case _ => throw new Exception("out of bound!")
}
}

this match {
That line means you are matching the containing object, in your case that is object StreamInt. That (companion) object can never be a Cons cell. You probably want to have the method nth on the class or trait StreamInt:
sealed trait StreamInt {
def nth(n:Int):Int= this match {
case Cons(hd,tl)=> if (n==0) hd else tl().nth(n-1)
case Empty => throw new Exception("out of bound!")
}
}
case object Empty extends StreamInt
case class Cons (hd: Int, tl: ()=>StreamInt) extends StreamInt
object StreamInt{
def cons(hd:Int, tl: => StreamInt):StreamInt = {
val head=hd
lazy val tail=tl
Cons(head, ()=>tail)
}
def empty:StreamInt = Empty
def apply(as: Int*):StreamInt={
if (as.isEmpty) empty
else cons(as.head, apply(as.tail: _*))
}
}
Now this refers to the trait StreamInt which may indeed by a Con or Empty.
I also added the sealed modifier, that ensures that the compiler can warn you if you miss a particular case when using pattern matching.

Related

How can I override toString for my List implementation?

Beginner question. I have a minimal List implementation:
sealed trait MyList[+A]
case object Nil 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) Nil
else Cons(as.head, apply(as.tail: _*))
private def toString(l: MyList[Any]): String = {
def f(l: MyList[Any]): String = {
l match {
case Nil => "]"
case Cons(x, Nil) => x.toString + "]"
case Cons(x, xs) => x.toString + ", " + f(xs)
}
}
"[" + f(l)
}
def main(args: Array[String]): Unit = {
println(toString(MyList(1, 2, 3)))
}
}
The output of this program is [1, 2, 3]. Is it possible to get the same output without explicitly calling the private method toString()? That is, to make this the default print output when calling println.
I have tried to add this overriding method:
override def toString: String = ...
But I ran into two problems. The first is that it's not actually affecting the output of println, no matter what this overriding method returns (even though println ultimately calls toString). The second is that I don't know how to print the list content without a parameter for the list itself (toString does not take any parameters, so I assume it must reference this, or something else?).
object MyList and trait MyList are 2 different classes in runtime, so whether you put toString in one or the other changes what will be overriden
sealed trait MyList[+A] {
override def toString = "x"
}
case object Nil extends MyList[Nothing]
case class Cons[+A](head: A, tail: MyList[A]) extends MyList[A]
object MyList {
// ...
override def toString = "y"
}
println(Nil)
println(Cons("string", Nil))
println(MyList)
Additionally case class/case object creates its own override def toString by default so if you want to override toString in both Nil and Cons I would suggest putting final before override def toString in sealed trait MyList[+A] to make sure it is respected.

object extends trait v.s class extends trait

What is the benefit we declare object Nil to extends TweetList?
why not still use class Nil?
trait TweetList {
def head: Tweet
def tail: TweetList
def isEmpty: Boolean
def foreach(f: Tweet => Unit): Unit =
if (!isEmpty) {
f(head)
tail.foreach(f)
}
}
object Nil extends TweetList {
def head = throw new java.util.NoSuchElementException("head of EmptyList")
def tail = throw new java.util.NoSuchElementException("tail of EmptyList")
def isEmpty = true
}
class Cons(val head: Tweet, val tail: TweetList) extends TweetList {
def isEmpty = false
}
Here's a link for how to use singleton class.
Above comments also mentioned about it, but I explain it again.
In scala, object declaration is used for singleton objects.
In this case, Nil's role is of representing 'emptiness' and is used as last parameters of successive cons
cons(a, Nil) => List(a)
cons(a, cons(b, Nil)) => List(a, b)
So why Nil is object and extends List? cause,
Nil is used as single representation of emptiness of List.
We don't need multiple instances of Nil.
It also makes sense that 2nd parameter of cons is List type.

Is there a `OneOf` class for grouping classes with no common ancestor

Similar to this, instead of wanting to accept one of several unrelated classes I'd like to return one.
I have an orchestrating service that utilizes several underlying Repositories. Each repo can pass back an error. However, these Error classes do not share a common ancestor.
For instance:
case class DistributionError
case class UserError
case class ContentError
I wanted to create my orchestrating service method like so:
def doSomethingComplicated(): Either[TheErrors, Boolean] = {
//...
case Failure(e) => Left(new DistributionError)
//...
}
Then I would invoke it like so:
doSomethingComplicated() match {
case Left(error) => {
error match {
case _: DistributionError => ...
case _: UserError => ...
case _: ContentError => ...
}
}
case Right(success) => ...
}
As per the linked SO answer, I tried:
class TheErrors[T]
object TheErrors {
implicit object DistWitness extends TheErrors[DistributionError]
implicit object UserWitness extends TheErrors[UserError]
implicit object ContentWitness extends TheErrors[ContentError]
}
But it just won't work the same way it does for parameters. The compiler always complains with:
> Error:(176, 48) type mismatch;
> found : UserError
> required: T
> case None => Left(UserError)
Is it even possible to use this method for return types?
AnyRef solution
The quick & cheap solution would be to drop the whole TheErrors typeclass, and simply return Either[AnyRef, Boolean] from doSomethingComplicated.
Existential types solution
If you absolutely want to ensure that doSomethingComplicated only returns types of errors that have previously been explicitly white-listed in TheErrors companion object, you can do this:
import scala.language.existentials
case class DistributionError()
case class UserError()
case class ContentError()
class TheErrors[T]
object TheErrors {
implicit object DistWitness extends TheErrors[DistributionError]
implicit object UserWitness extends TheErrors[UserError]
implicit object ContentWitness extends TheErrors[ContentError]
}
def allowedError[E](e: E)(implicit witness: TheErrors[E])
: (E, TheErrors[E]) = (e, witness)
type AllowedError = (E, TheErrors[E]) forSome { type E }
def doSomethingComplicated(): Either[AllowedError, Boolean] = {
import TheErrors._
/* sth complicated */ Left(allowedError(DistributionError()))
}
doSomethingComplicated() match {
case Left((error, _)) => {
error match {
case _: DistributionError => 42
case _: UserError => 58
case _: ContentError => 100
}
}
case Right(success) => 2345678
}
Essentially, all it does is checking for an existence of a TheErrors-witness when you call allowedError, and attaching the witness to the error. This makes sure that only the errors for which the witnesses can be found are returned from doSomethingComplicated. Note however, that it does not help you to check the exhaustiveness of the pattern matching. For this, you would have to take the usual path, and wrap all your errors into subclasses of one common sealed trait.
Sealed trait solution
import scala.language.implicitConversions
case class DistributionError()
case class UserError()
case class ContentError()
sealed trait TheErrors
case class Distr(e: DistributionError) extends TheErrors
case class User(e: UserError) extends TheErrors
case class Content(e: ContentError) extends TheErrors
object TheErrors {
implicit def apply(d: DistributionError): TheErrors = Distr(d)
implicit def apply(d: UserError): TheErrors = User(d)
implicit def apply(d: ContentError): TheErrors = Content(d)
}
def doSomethingComplicated(): Either[TheErrors, Boolean] = {
/* sth complicated */ Left(DistributionError())
}
doSomethingComplicated() match {
case Left(error) => {
error match {
case Distr(e) => 42
case User(e) => 58
case Content(e) => 100
}
}
case Right(success) => 2345678
}
Implicit conversion + plain old subclass polymorphism
With implicit conversions and good old subclass polymorphism, you can get rid of any specific TheErrors subclasses in both doSomethingComplicated and in the caller code:
import scala.language.implicitConversions
case class DistributionError()
case class UserError()
case class ContentError()
sealed trait TheErrors {
def error: AnyRef
}
object TheErrors {
private case class TheError(val error: AnyRef) extends TheErrors
implicit def apply(d: DistributionError): TheErrors = TheError(d)
implicit def apply(d: UserError): TheErrors = TheError(d)
implicit def apply(d: ContentError): TheErrors = TheError(d)
}
def doSomethingComplicated(): Either[TheErrors, Boolean] = {
/* sth complicated */ Left(DistributionError())
}
doSomethingComplicated() match {
case Left(e) => {
e.error match {
case _: DistributionError => 42
case _: UserError => 58
case _: ContentError => 100
}
}
case Right(success) => 2345678
}
Few options:
Use Shapeless's Coproduct type
Use Any
Nested Either i.e. Either[Either[Either[A, B], C], D]
Define your own sealed trait with subclasses that just wrap their corresponding types i.e. class UserErrorWrapper(val u: UserError) extends MyErrorTrait
Wait for Dotty and use a union type

spray-json serialization in spray-routing with custom JsonFormats

Using Spray with spray-json for a system, version:
"io.spray" %% "spray-json" % "1.2.6"
I cannot figure how to get custom JsonFormat definitions to work for serialization that is being handled by spray-routing.
I've had two separate circumstances that have failed.
1. Nested Case Classes
Basic case class JSON serialization has worked fine
case class Something(a: String, b: String)
implicit val something2Json = jsonFormat3(Something)
However if I have a nested case class in the case class to be serialized, I can resolve compile issues by providing another JsonFormat implicit, yet at run-time it refuses to serialize
case class Subrecord(value: String)
case class Record(a: String, b: String, subrecord: Subrecord)
object MyJsonProtocol extends DefaultJsonProtocol {
implicit object SubrecordJsonFormat extends JsonFormat[Subrecord] {
def write(sub: Subrecord) = JsString(sub.value)
def read(value: JsValue) = value match {
case JsString(s) => Subrecord(s)
case _ => throw new DeserializationException("Cannot parse Subrecord")
}
}
implicit val record2Json = jsonFormat3(Record)
}
This will throw a MappingException at runtime, explaining there is no usable value for subrecord
2. Trait with various 0-N case extensions
Here I have a trait that serves as a capturing type for a group of case classes. Some of the extending classes have vals while others have no vals and are objects. When serialization occurs, it seems like my implicit defined JsonFormat is completely ignored and I'm just give an empty JsObject, particularly when the actual underlying type was one of the case object's with no vals.
sealed trait Errors
sealed trait ErrorsWithReason extends Errors {
def reason: String
}
case class ValidationError(reason: String) extends ErrorsWithReason
case object EntityNotFound extends Errors
case class DatabaseError(reason: String) extends ErrorsWithReason
object MyJsonProtocol extends DefaultJsonProtocol {
implicit object ErrorsJsonFormat extends JsonFormat[Errors] {
def write(err: Errors) = failure match {
case e: ErrorsWithReason => JsString(e.reason)
case x => JsString(x.toString())
}
def read(value: JsValue) = {
value match {
//Really only intended to serialize to JSON for API responses
case _ => throw new DeserializationException("Can't reliably deserialize Error")
}
}
}
}
So given the above, if the actual type being serialized is EntityNotFound, then the serialization becomes a RootJsonFormat turning into {}. If it's an ErrorsWithReason then it becomes a RootJsonFormat turning into { "reason": "somevalue" }. I may be confused with how the JsonFormat definition is supposed to work, but it doesn't seem to be using my write method at all and instead has suddenly figured out how to serialize on its own.
EDIT
Specific serialization cases are using read/deserialization like:
entity(as[JObject]) { json =>
val extraction: A = json.extract[A]
}
And write/serialization with the complete directive.
I now am realizing thanks to the first answer posted here that my JsonDefaultProtocol and JsonFormat implementations are for spray-json classes, meanwhile the entity directive extraction in the deserialization is using json4s JObject as opposed to spray-json JsObject.
Another approach for clean JSON output
import spray.json._
import spray.json.DefaultJsonProtocol._
// #1. Subrecords
case class Subrecord(value: String)
case class Record(a: String, b: String, subrecord: Subrecord)
implicit object RecordFormat extends JsonFormat[Record] {
def write(obj: Record): JsValue = {
JsObject(
("a", JsString(obj.a)),
("b", JsString(obj.b)),
("reason", JsString(obj.subrecord.value))
)
}
def read(json: JsValue): Record = json match {
case JsObject(fields)
if fields.isDefinedAt("a") & fields.isDefinedAt("b") & fields.isDefinedAt("reason") =>
Record(fields("a").convertTo[String],
fields("b").convertTo[String],
Subrecord(fields("reason").convertTo[String])
)
case _ => deserializationError("Not a Record")
}
}
val record = Record("first", "other", Subrecord("some error message"))
val recordToJson = record.toJson
val recordFromJson = recordToJson.convertTo[Record]
println(recordToJson)
assert(recordFromJson == record)
If you need both reads and writes you can do it this way:
import spray.json._
import spray.json.DefaultJsonProtocol._
// #1. Subrecords
case class Subrecord(value: String)
case class Record(a: String, b: String, subrecord: Subrecord)
implicit val subrecordFormat = jsonFormat1(Subrecord)
implicit val recordFormat = jsonFormat3(Record)
val record = Record("a", "b", Subrecord("c"))
val recordToJson = record.toJson
val recordFromJson = recordToJson.convertTo[Record]
assert(recordFromJson == record)
// #2. Sealed traits
sealed trait Errors
sealed trait ErrorsWithReason extends Errors {
def reason: String
}
case class ValidationError(reason: String) extends ErrorsWithReason
case object EntityNotFound extends Errors
case class DatabaseError(reason: String) extends ErrorsWithReason
implicit object ErrorsJsonFormat extends JsonFormat[Errors] {
def write(err: Errors) = err match {
case ValidationError(reason) =>
JsObject(
("error", JsString("ValidationError")),
("reason", JsString(reason))
)
case DatabaseError(reason) =>
JsObject(
("error", JsString("DatabaseError")),
("reason", JsString(reason))
)
case EntityNotFound => JsString("EntityNotFound")
}
def read(value: JsValue) = value match {
case JsString("EntityNotFound") => EntityNotFound
case JsObject(fields) if fields("error") == JsString("ValidationError") =>
ValidationError(fields("reason").convertTo[String])
case JsObject(fields) if fields("error") == JsString("DatabaseError") =>
DatabaseError(fields("reason").convertTo[String])
}
}
val validationError: Errors = ValidationError("error")
val databaseError: Errors = DatabaseError("error")
val entityNotFound: Errors = EntityNotFound
assert(validationError.toJson.convertTo[Errors] == validationError)
assert(databaseError.toJson.convertTo[Errors] == databaseError)
assert(entityNotFound.toJson.convertTo[Errors] == entityNotFound)

Narrowing with ClassTag

I am trying to narrow a generic type. It compiles, but the result is not the intended one (Container(A), Container(B) ..) instead of (Container(A),Container(A)).
What am I doing wrong?
sealed trait Base
case class A() extends Base
case class B() extends Base
case class Container[+T](item: Base)
object Test {
import scala.reflect.ClassTag
def narrowContainer[T <: Base](list: List[Container[Base]])(implicit tag: ClassTag[T]): List[Container[T]] = {
list.collect{ case t: Container[T] => t }
}
def testNarrowContainer(){
val li = List(A(),B(),A(),B()).map(Container(_))
println(narrowContainer[A](li))
println(narrowContainer[B](li))
}
def main(args: Array[String]){
testNarrowContainer()
}
}
In this expression T gets erased, so all the case actually checks is that t is a Container
{ case t: Container[T] => t }
I think you can add a guard explicitly checking the contents of t against tag (sorry, don't know the correct syntax for that right now)