I saw anwser here but i dont have Object Empty and i have leaf not just everthing in Node like this :
case class Node ( val e : Int ,left : BinaryTree, right : BinaryTree).
I have problem with adding Leaf as param in this def sums.
import scala.annotation.tailrec
/**
* #author emil
*/
class tree {
}
sealed abstract class BinaryTree
case class Node (left : BinaryTree, right : BinaryTree) extends BinaryTree
case class Leaf (value : Int) extends BinaryTree
object Main {
def main(args : Array[String]) {
val tree = Node(Node(Leaf(1),Leaf(3)), Node(Leaf(5),Leaf(7)));
println(tree)
sum(tree)
}
def sum(bin: BinaryTree) = {
def sums(trees: List[BinaryTree], acc: Int): Int = trees match {
case Nil => acc
case Node(l, r) :: rs => sums(l :: r :: rs, acc)
}
sums(List(bin),0)
}
}
If I understand what you want to do is something like
case Leaf(v) :: rs => sums(xs, acc+v)
May be:
def sum(bin: BinaryTree) = {
def sums(t: BinaryTree): Int = t match {
case Leaf(v) => v
case Node(l, r) => sums(l) + sums(r)
}
sums(bin)
}
val res = sum(tree)
println(res) // 16
Related
so this is my macro
package com.fullfacing.ticketing.macros
import com.mongodb.DBObject
import scala.language.experimental.macros
import scala.reflect.macros.whitebox.Context
/**
* Project: com.fullfacing.ticketing.macros
* Created on 2015/05/26.
* ryno aka lemonxah -
* https://github.com/lemonxah
* http://stackoverflow.com/users/2919672/lemon-xah
*/
trait Mappable[A,B] {
def toDBType(a: A): B
def fromDBType(b: B): A
}
object MongoMappable {
implicit def materializeMappable[A]: Mappable[A, DBObject] = macro materializeMappableImpl[A]
def materializeMappableImpl[A: c.WeakTypeTag](c: Context): c.Expr[Mappable[A, DBObject]] = {
import c.universe._
val tpe = weakTypeOf[A]
val companion = tpe.typeSymbol.companion
val fields = tpe.decls.collectFirst {
case m: MethodSymbol if m.isPrimaryConstructor ⇒ m
}.get.paramLists.head
val (toDBObject, fromDBObject) = fields.map { field ⇒
val name = field.name.toTermName
val decoded = name.decodedName.toString
val returnType = tpe.decl(name).typeSignature
(q"$decoded → t.$name", q"dbo.as[$returnType]($decoded)")
}.unzip
c.Expr[Mappable[A,DBObject]] { q"""
new Mappable[$tpe] {
def toMap(t: $tpe): DBObject = MongoDBObject(..$toDBObject)
def fromMap(dbo: DBObject): $tpe = $companion(..$fromDBObject)
}
""" }
}
}
and this is how i am using it
package com.fullfacing.ticketing.common.dao
import com.fullfacing.ticketing.common.model._
import com.fullfacing.ticketing.macros.{MongoMappable, Mappable}
import com.fullfacing.ticketing.macros.MongoMappable._
import com.mongodb.DBObject
import com.mongodb.casbah.commons.MongoDBObject
import com.mongodb.casbah.Imports._
import com.mongodb.casbah.query.Imports
/**
* Project: com.fullfacing.liono.common.data.dao
* Created on 2015/05/11.
* ryno aka lemonxah -
* https://github.com/lemonxah
* http://stackoverflow.com/users/2919672/lemon-xah
*/
class MongoDAO[A <: Model](coll: MongoCollection) extends DAO[A, DBObject] {
import MongoDAO._
def interpreter(q: Query): Option[DBObject] = {
def loop(q: Query, acc: MongoDBObject): Imports.DBObject = q match {
case Or(left, right) => acc ++ $or(loop(left, MongoDBObject()), loop(right, MongoDBObject()))
case And(left, right) => acc ++ $and(loop(left, MongoDBObject()), loop(right, MongoDBObject()))
case Equals(f, v: Int) => f.name $eq v
case Equals(f, v: String) => f.name $eq v
case GreaterOrEqual(f, v: Int) => f.name $gte v
case GreaterThan(f, v: Int) => f.name $gt v
case LessOrEqual(f, v: Int) => f.name $lte v
case LessThan(f, v: Int) => f.name $lt v
case NotEquals(f, v: Int) => f.name $ne v
case NotEquals(f, v: String) => f.name $ne v
case _ => throw new UnsupportedOperationException()
}
try { Some(loop(q,MongoDBObject())) } catch {
case e: UnsupportedOperationException => None
}
}
override def list: Vector[A] = {
coll.find().toVector.map(mapf)
}
override def filter(query: Query): Vector[A] = {
interpreter(query) match {
case Some(q) => coll.find(q).toVector.map(mapf)
case None => Vector()
}
}
override def headOption(query: Query): Option[A] = {
interpreter(query) match {
case Some(q) => coll.find(q).toVector.map(mapf).headOption
case None => None
}
}
def insert(a: A) {
coll.insert(MongoDAO.mapt[A](a))
}
def update(a: A): Unit = {
// val q = MongoDBObject("id" -> a.id.id)
// val u = $set(toMap(a).toList: _*)
// coll.update(q,u)
}
override def delete(a: A): Unit = ???
override def delete(query: Query): Unit = {
interpreter(query) match {
case Some(q) => coll.findAndRemove(q)
case None =>
}
}
}
object MongoDAO {
def apply[A <: Model](coll: MongoCollection): MongoDAO[A] = new MongoDAO[A](coll)
def mapt[A: Mappable](a: A) = implicitly[Mappable[A, DBObject]].toDBType(a)
def mapf[A: Mappable](b: DBObject) = implicitly[Mappable[A, DBObject]].fromDBType(b)
}
well that is how i want to be using it
this is my DAO trait and the query AST for the interpreter
package com.fullfacing.ticketing.common.dao
import com.fullfacing.ticketing.common.model.Model
/**
* Project: com.fullfacing.liono.common.data.dao
* Created on 2015/05/19.
* ryno aka lemonxah -
* https://github.com/lemonxah
* http://stackoverflow.com/users/2919672/lemon-xah
*/
trait DAO[A <: Model, B] {
def interpreter(q: Query): Option[B]
def +=(a: A) = insert(a)
def insert(a: A)
def list: Vector[A]
def filter(query: Query): Vector[A]
def headOption(query: Query): Option[A]
def update(a: A)
def delete(a: A)
def delete(query: Query)
}
case class Field[A](name: String) {
def ===(value: A): Query = Equals(this, value)
def !==(value: A): Query = NotEquals(this, value)
def <(value: A): Query = LessThan(this, value)
def >(value: A): Query = GreaterThan(this, value)
def >=(value: A): Query = GreaterOrEqual(this, value)
def <=(value: A): Query = LessOrEqual(this, value)
}
sealed trait Query { self =>
def &&(t: Query): Query = and(t)
def and(t: Query): Query = And(self, t)
def ||(t: Query): Query = or(t)
def or(t: Query): Query = Or(self, t)
}
sealed trait Operator extends Query { def left: Query; def right: Query}
case class Or(left: Query, right: Query) extends Operator
case class And(left: Query, right: Query) extends Operator
sealed trait Operand[+A] extends Query { def field: Field[_]; def value: A }
case class GreaterOrEqual[A](field: Field[A], value: A) extends Operand[A]
case class GreaterThan[A](field: Field[A], value: A) extends Operand[A]
case class LessOrEqual[A](field: Field[A], value: A) extends Operand[A]
case class LessThan[A](field: Field[A], value: A) extends Operand[A]
case class Equals[A](field: Field[A], value: A) extends Operand[A]
case class NotEquals[A](field: Field[A], value: A) extends Operand[A]
the idea of all of this is so that i can make new DAOs like the MongoDAO and i dont have to change a lot of code just add a db implementation and all the top level code stays the same, maybe change a import or use a different db context and it should just work.
but while doing this i am getting this issue
Error:(81, 50) not enough arguments for method implicitly: (implicit e: com.fullfacing.ticketing.macros.Mappable[A,com.mongodb.DBObject])com.fullfacing.ticketing.macros.Mappable[A,com.mongodb.DBObject].
Unspecified value parameter e.
def mapf[A: Mappable](b: DBObject) = implicitly[Mappable[A, DBObject]].fromDBType(b)
^
i am not sure if what i want to do is possible like this .. but i want to refrain from having make mappers like the following manually.
object DeviceMap extends DAOMap[Device, DBObject] {
def mapt(device: Device): DBObject = {
MongoDBObject(
"uuid" -> device.uuid,
"created" -> device.created,
"id" -> device.id.id
)
}
def mapf(o: DBObject): Device = {
Device(
uuid = o.as[String]("uuid"),
created = o.as[Long]("created"),
id = Id(o.as[UUID]("id"))
)
}
}
because that would be very tedious to do it for all the data objects that will be implemented in the final version of this tool
I have a tree defined as
sealed trait Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
I would like a function to count the number of nodes in the tree and a function that counts the number of leafs
(I wrote a function to counts the number of leafs but I am not satisfied of the method that I am using. I would like a more "functional" implementation of that one).
val t1 = Branch(
Branch(
Leaf(12),
Branch(
Leaf(3),
Leaf(4))),
Leaf(8)) //> t1 : trees.Branch[Int] = Branch(Branch(Leaf(12),Branch(Leaf(3),Leaf(4))),Le
//| af(8))
def n_nodes(t:Tree[Int]):Int = {
var s = 0
def n_nodesAcc(t:Tree[Int]):Unit = {
t match {
case Branch(left, right) =>{
n_nodesAcc(left)
n_nodesAcc(right )
}
case Leaf(v) => {s = s+ 1}
}
}
n_nodesAcc(t)
s
} //> n_nodes: (t: trees.Tree[Int])Int
n_nodes(t1) //> res0: Int = 4
(this is an exercise)
You might write a recursive method to count the leaves:
def countLeaves[A](tree: Tree[A]): Int = tree match {
case l:Leaf[A] => 1
case b:Branch[A] => countLeaves(b.left) + countLeaves(b.right)
}
Or count all the nodes:
def countNodes[A](tree: Tree[A]): Int = tree match {
case l:Leaf[A] => 1
case b:Branch[A] => 1 + countLeaves(b.left) + countLeaves(b.right)
}
You could also write a similar method to just get all the leaves, and you could have more flexibility to do different functions later:
def getLeaves[A](tree: Tree[A]): Seq[Leaf[A]] = tree match {
case l:Leaf[A] => Seq(l)
case b:Branch[A] => getLeaves(b.left) ++ getLeaves(b.right)
}
And then count with getLeaves(t1).length. Or, similarly, get all the nodes:
def getNodes[A](tree: Tree[A]): Seq[Tree[A]] = tree match {
case l:Leaf[A] => Seq(l)
case b:Branch[A] => Seq(b) ++ getNodes(b.left) ++ getNodes(b.right)
}
I want to define a method, which will return a Future. And in this method, it will call another service which returns also a Future.
We have defined a BusinessResult to represent Success and Fail:
object validation {
trait BusinessResult[+V] {
def flatMap[T](f: V => BusinessResult[T]):BusinessResult[T]
def map[T](f: V => T): BusinessResult[T]
}
sealed case class Success[V](t:V) extends BusinessResult[V] {
def flatMap[T](f: V => BusinessResult[T]):BusinessResult[T] = {
f(t)
}
def map[T](f: V => T): BusinessResult[T] = {
Success(f(t))
}
}
sealed case class Fail(e:String) extends BusinessResult[Nothing] {
def flatMap[T](f: Nothing => BusinessResult[T]):BusinessResult[T] = this
def map[T](f: Nothing => T): BusinessResult[T] = this
}
}
And define the method:
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import validation._
def name: BusinessResult[String] = Success("my name")
def externalService(name:String):Future[String] = future(name)
def myservice:Future[Int] = {
for {
n <- name
res <- externalService(n)
} yield res match {
case "ok" => 1
case _ => 0
}
}
But which is not compilable. The code in myservice can't return a Future[Int] type.
I also tried to wrap the name with Future:
def myservice:Future[Int] = {
for {
nn <- Future.successful(name)
n <- nn
res <- externalService(n)
} yield res match {
case "ok" => 1
case _ => 0
}
}
Which is also not compilable.
I know there must be a lot of issues in this code. How can I adjust them to make it compilable?
If you change the n with some hardcoded string it works, the problem is that in the for comprehension the variable n has type BusinessResult[String], as you probably already know for comprehension desugarize to map, flatMap and filter so the first part n <- name desugarize to a map on name:
val test: BusinessResult[String] = name.map(x => x)
Intellij thinks n is a String but the scala compiler disagree:
type mismatch;
[error] found : validation.BusinessResult[Nothing]
[error] required: scala.concurrent.Future[Int]
[error] n <- name
[error] ^
Easy solution could be to add a getter method to get back the string and do something like Option does:
object validation {
trait BusinessResult[+V] {
def flatMap[T](f: V => BusinessResult[T]):BusinessResult[T]
def map[T](f: V => T): BusinessResult[T]
def getVal: V
}
sealed case class Success[V](t:V) extends BusinessResult[V] {
def flatMap[T](f: V => BusinessResult[T]):BusinessResult[T] = {
f(t)
}
def map[T](f: V => T): BusinessResult[T] = {
Success(f(t))
}
def getVal: V = t
}
sealed case class Fail(e:String) extends BusinessResult[Nothing] {
def flatMap[T](f: Nothing => BusinessResult[T]):BusinessResult[T] = this
def map[T](f: Nothing => T): BusinessResult[T] = this
def getVal = throw new Exception("some message")
}
}
def myservice: Future[Int] = {
val value = name.getVal
for {
res <- externalService(value)
} yield res match {
case "ok" => 1
case _ => 0
}
}
Note that you can't extract the name in the for comprehension since map on String return Chars
I have been searching the forum and Google for answers to type erasure issues for Scala. However, I cannot find anything that answers my question.
I struggling with pattern matching on objects that match the type parameter of ParamClass. I need to pattern match on the type of incoming objects to the bar method. I have seen solutions such as
bar[X](a : X)(implicit m : Manifest[X])
which would solve my problem, but I cannot use this as the bar method is an overridden method. (Actually is the receive partial function in the Akka actor framework). The code is given below and should be self explanatory:
class ParamClass[A : Manifest] {
def bar(x : Any) = x match {
case a: A => println("Found A: " + a)
case _ => println("No match: " + x)
}
}
object ErasureIssue {
def main(args: Array[String]) {
val clz = new ParamClass[Int]
clz.bar("faf")
clz.bar(2.3)
clz.bar(12) // this should match, but does not
}
}
ErasureIssue.main(null)
Any help on solving this issue is greatly appreciated. I'm using Scala 2.9.1, BTW.
-J
In theory you could check in bar like this: x.getClass == implicitly[Manifest[A]].erasure, but that fails for primitive types such as Int for which the manifest correctly erases to Int, but bar is called with boxed type java.lang.Integer ... :-(
You could require A to be an AnyRef in order to get the boxed manifest:
class ParamClass[A <: AnyRef : Manifest] {
def bar(x : Any) = x match {
case _ if x.getClass == implicitly[Manifest[A]].erasure =>
println("Found A: " + x.asInstanceOf[A])
case _ => println("No match: " + x)
}
}
object ErasureIssue {
def main(args: Array[String]) {
val clz = new ParamClass[Integer] // not pretty...
clz.bar("faf")
clz.bar(2.3)
clz.bar(12) // ok
}
}
ErasureIssue.main(null)
Given your requirement to construct primitive arrays, you could store directly the boxed class, independently of the unboxed manifest:
object ParamClass {
def apply[A](implicit mf: Manifest[A]) = {
val clazz = mf match {
case Manifest.Int => classOf[java.lang.Integer] // boxed!
case Manifest.Boolean => classOf[java.lang.Boolean]
case _ => mf.erasure
}
new ParamClass[A](clazz)
}
}
class ParamClass[A] private[ParamClass](clazz: Class[_])(implicit mf: Manifest[A]) {
def bar(x : Any) = x match {
case _ if x.getClass == clazz =>
println("Found A: " + x.asInstanceOf[A])
case _ => println("No match: " + x)
}
def newArray(size: Int) = new Array[A](size)
override def toString = "ParamClass[" + mf + "]"
}
val pi = ParamClass[Int]
pi.bar("faf")
pi.bar(12)
pi.newArray(4)
val ps = ParamClass[String]
ps.bar("faf")
ps.bar(12)
ps.newArray(4)
If you try to compile with -unchecked, you immediately get the warning.
test.scala:3: warning: abstract type A in type pattern A is unchecked
since it is eliminated by erasure
case a: A => println("Found A: " + a)
If you now want to go deeper, you can use scalac -print
[[syntax trees at end of cleanup]]// Scala source: test.scala
package <empty> {
class ParamClass extends java.lang.Object with ScalaObject {
def bar(x: java.lang.Object): Unit = {
<synthetic> val temp1: java.lang.Object = x;
if (temp1.$isInstanceOf[java.lang.Object]())
{
scala.this.Predef.println("Found A: ".+(temp1))
}
else
{
scala.this.Predef.println("No match: ".+(x))
}
};
def this(implicit evidence$1: scala.reflect.Manifest): ParamClass = {
ParamClass.super.this();
()
}
};
final object ErasureIssue extends java.lang.Object with ScalaObject {
def main(args: Array[java.lang.String]): Unit = {
val clz: ParamClass = new ParamClass(reflect.this.Manifest.Int());
clz.bar("faf");
clz.bar(scala.Double.box(2.3));
clz.bar(scala.Int.box(12))
};
def this(): object ErasureIssue = {
ErasureIssue.super.this();
()
}
}
}
Now seeing this code you can see that your A has turned into a java.lang.Object, which cause all the parameters to match the clause
Is it possible to perform a pattern match whose result conforms to a type parameter of the outer method? E.g. given:
trait Key[A] {
def id: Int
def unapply(k: Key[_]): Boolean = k.id == id // used for Fail2
def apply(thunk: => A): A = thunk // used for Fail3
}
trait Ev[A] {
def pull[A1 <: A](key: Key[A1]): Option[A1]
}
trait Test extends Ev[AnyRef] {
val key1 = new Key[String] { def id = 1 }
val key2 = new Key[Symbol] { def id = 2 }
}
Is there an implementation of Test (its pull method) which uses a pattern match on the key argument and returns Option[A1] for each key checked, without the use of asInstanceOf?
Some pathetic tries:
class Fails1 extends Test {
def pull[A1 <: AnyRef](key: Key[A1]): Option[A1] = key match {
case `key1` => Some("hallo")
case `key2` => Some('welt)
}
}
class Fails2 extends Test {
def pull[A1 <: AnyRef](key: Key[A1]): Option[A1] = key match {
case key1() => Some("hallo")
case key2() => Some('welt)
}
}
class Fails3 extends Test {
def pull[A1 <: AnyRef](key: Key[A1]): Option[A1] = key match {
case k # key1() => Some(k("hallo"))
case k # key2() => Some(k('welt))
}
}
None works, obviously... The only solution is to cast:
class Ugly extends Test {
def pull[A1 <: AnyRef](key: Key[A1]): Option[A1] = key match {
case `key1` => Some("hallo".asInstanceOf[A1])
case `key2` => Some('welt .asInstanceOf[A1])
}
}
val u = new Ugly
u.pull(u.key1)
u.pull(u.key2)
The problem is indeed that pattern matching ignores all erased types. However, there is a little implicit trickery that one could employ. The following will preserve the type resolution provided by the match for the return type.
abstract class UnErased[A]
implicit case object UnErasedString extends UnErased[String]
implicit case object UnErasedSymbol extends UnErased[Symbol]
class UnErasedTest extends Test {
def pull[ A1 <: AnyRef ]( key: Key[ A1 ])(implicit unErased: UnErased[A1]): Option[ A1 ] = unErased match {
case UnErasedString if key1.id == key.id => Some( "hallo" )
case UnErasedSymbol if key2.id == key.id => Some( 'welt )
case _ => None
}
}
val u = new UnErasedTest
println( u.pull( u.key1 ) )
println( u.pull( u.key2 ) )
This is however nearly equivalent to just defining separate sub classes of Key. I find the following method preferable however it may not work if existing code is using Key[String] that you can't change to the necessary KeyString (or too much work to change).
trait KeyString extends Key[String]
trait KeySymbol extends Key[Symbol]
trait Test extends Ev[ AnyRef ] {
val key1 = new KeyString { def id = 1 }
val key2 = new KeySymbol { def id = 2 }
}
class SubTest extends Test {
def pull[ A1 <: AnyRef ]( key: Key[ A1 ]): Option[ A1 ] = key match {
case k: KeyString if key1.id == k.id => Some( "hallo" )
case k: KeySymbol if key2.id == k.id => Some( 'welt )
case _ => None
}
}
val s = new SubTest
println( s.pull( s.key1 ) )
println( s.pull( s.key2 ) )
I provide here an extended example (that shows more of my context) based on the closed types approach of Neil Essy's answer:
trait KeyLike { def id: Int }
trait DispatchCompanion {
private var cnt = 0
sealed trait Value
sealed trait Key[V <: Value] extends KeyLike {
val id = cnt // automatic incremental ids
cnt += 1
}
}
trait Event[V] {
def apply(): Option[V] // simple imperative invocation for testing
}
class EventImpl[D <: DispatchCompanion, V <: D#Value](
disp: Dispatch[D], key: D#Key[V]) extends Event[V] {
def apply(): Option[V] = disp.pull(key)
}
trait Dispatch[D <: DispatchCompanion] {
// factory method for events
protected def event[V <: D#Value](key: D#Key[V]): Event[V] =
new EventImpl[D, V](this, key)
def pull[V <: D#Value](key: D#Key[V]): Option[V]
}
Then the following scenario compiles with not too much clutter:
object Test extends DispatchCompanion {
case class Renamed(before: String, now: String) extends Value
case class Moved (before: Int , now: Int ) extends Value
private case object renamedKey extends Key[Renamed]
private case object movedKey extends Key[Moved ]
}
class Test extends Dispatch[Test.type] {
import Test._
val renamed = event(renamedKey)
val moved = event(movedKey )
// some dummy propagation for testing
protected def pullRenamed: (String, String) = ("doesn't", "matter")
protected def pullMoved : (Int , Int ) = (3, 4)
def pull[V <: Value](key: Key[V]): Option[V] = key match {
case _: renamedKey.type => val p = pullRenamed; Some(Renamed(p._1, p._2))
case _: movedKey.type => val p = pullMoved; Some(Moved( p._1, p._2))
}
}
...and yields the desired results:
val t = new Test
t.renamed()
t.moved()
Now the only thing I don't get and I find ugly is that my cases must be of the form
case _: keyCaseObject.type =>
and cannot be
case keyCaseObject =>
which I would very much prefer. Any ideas where this limitation comes from?