In a Groovy class I want to expose internal String property as a List through getters and setters. I want the property to behave just like a regular list property to which I can add element using obj.list << newElement. However it does not work and I have to use work-around obj.list = obj.list << newElement.
Is there any other way to do the trick in Groovy? Any method to be implemented in the class, that will be called when << operator is used?
Code example:
class Test {
String internal = 'a,b,c'
List getList() {
return internal .split(',')
}
void setList(List list) {
internal = list.join(',')
}
}
def t = new Test()
println t.internal // a,b,c
println t.list // [a, b, c]
t.list << 'd' // this does not work! does not add new element
println t.list // [a, b, c]
t.list = t.list << 'd' // work-around that works
println t.list // [a, b, c, d]
Consider the following:
class Test {
String internal = 'a,b,c'
List getList() {
def list = internal.split(',') as List
// this will override so:
// << 'd' becomes appendToList(['d'])
// << ['e','f'] becomes appendToList(['e','f'])
list.metaClass.leftShift = { def x ->
this.appendToList([x].flatten())
}
return list
}
void appendToList(List list) {
internal = internal + "," + list.join(',')
}
void setList(List list) {
internal = list.join(',')
}
}
Note it handles both cases of (a) one item (b) a list of items
def t = new Test()
t.list << 'd'
assert ['a','b','c','d'] == t.list
t.list << ['e','f']
assert ['a','b','c','d','e','f'] == t.list
t.list = ['x','y']
assert ['x', 'y'] == t.list
Try with the following code,
Test t = new Test()
List list = t.getList()
list << 'd'
println list.dump()
Related
I'm trying to implement a Banker's Queue in Scala, and keep encountering the head of empty list runtime error around line 13. A Banker's Queue enqueues into one stack (push to s1), and dequeues from the other stack (pop from s1 and push to s2 (in reverse order just because)).
Since I'm using vals that are immutable, I cannot 'pop' from either s1 or s2.
So when s2 is Nil (empty list) and a dequeue operation is called, I need to add every value in s1 to s2, and return two values: s2.head, and a new TwoStackQueue object consisting of the empty list s1 (because I 'emptied' the entire list), and s2.tail.
As previously mentioned, if s2 is empty, I need to transfer all values from s1. This means s1 is 'empty', and so I reasoned that in this case, I'd need to pass an empty list to the TwoStackQueue constructor. However, I cannot get past the head of empty list error that's thrown at me.
I'd greatly appreciate any insight to my problem. Thank you!
class TwoStackQueue[A](s1 : List[A], s2 : List[A]) {
def this() = this(Nil, Nil) // auxiliary constructor
def enqueue(x : A) : TwoStackQueue[A] = {
new TwoStackQueue(s1:+x, s2);
}
def dequeue() : (A, TwoStackQueue[A]) = {
if(s2.isEmpty) {
s2 ::: s1.reverse;
(s2.head, new TwoStackQueue(List.empty[A], s2.tail));
} else {
(s2.head, new TwoStackQueue(s1, s2.tail));
}
}
}
object TwoStackQueue {
def main(args : Array[String]) = {
val q1 = new TwoStackQueue[Int]();
val q2 = q1.enqueue(1);
val q3 = q2.enqueue(2);
val (x,q4) = q3.dequeue()
println(x); // Should print 1
val q5 = q4.enqueue(3);
val (y,q6) = q5.dequeue()
println(y); // Should print 2
val (z,q7) = q6.dequeue()
println(z); // Should print 3
}
}
I've come across this operator in a Scala implementation of a graph (that you can find the example here, where two lists are interponed the operator -- and also two Maps.
abstract class GraphBase[T, U] {
case class Edge(n1: Node, n2: Node, value: U) {
def toTuple = (n1.value, n2.value, value)
}
case class Node(value: T) {
var adj: List[Edge] = Nil
// neighbors are all nodes adjacent to this node.
def neighbors: List[Node] = adj.map(edgeTarget(_, this).get)
}
var nodes: Map[T, Node] = Map()
var edges: List[Edge] = Nil
// If the edge E connects N to another node, returns the other node,
// otherwise returns None.
def edgeTarget(e: Edge, n: Node): Option[Node]
override def equals(o: Any) = o match {
case g: GraphBase[_,_] => (nodes.keys.toList -- g.nodes.keys.toList == Nil &&
edges.map(_.toTuple) -- g.edges.map(_.toTuple) == Nil)
case _ => false
}
def addNode(value: T) = {
val n = new Node(value)
nodes = Map(value -> n) ++ nodes
n
}
}
My current interpreter does not recognize it, so I am wondering where is this operator coming from? Does it mean list subtraction?
Is it valid Scala code?
You can alter an implementation of equals method to avoid usage of --:
override def equals(o: Any) = o match {
case g: GraphBase[_,_] => (nodes.keySet == g.nodes.keySet &&
edges.map(_.toTuple).toSet == g.edges.map(_.toTuple).toSet)
case _ => false
}
I'm using scalaz' Monad.whileM_ to implement a while loop in a functional way as follows:
object Main {
import scalaz._
import Scalaz._
import scala.language.higherKinds
case class IState(s: Int)
type IStateT[A] = StateT[Id, IState, A]
type MTransT[S[_], A] = EitherT[S, String, A]
type MTrans[A] = MTransT[IStateT, A]
def eval(k: Int): MTrans[Int] = {
for {
state <- get[IState].liftM[MTransT]
_ <- put(state.copy(s = (state.s + 1) % k)).liftM[MTransT]
} yield (k + 1)
}
def evalCond(): MTrans[Boolean] = {
for {
state <- get[IState].liftM[MTransT]
} yield (state.s != 0)
}
def run() = {
val k = 10
eval(k).whileM_(evalCond()).run(IState(1))
}
}
While this works for small k, it results in a StackOverflow error for large k (e.g. 1000000). Is there a way to trampoline whileM_ or is there a better way to be stack safe?
Use scalaz.Free.Trampoline instead of scalaz.Id.Id.
type IStateT[A] = StateT[Trampoline, IState, A]
The state operations used here return State[S, A] which is just an alias for StateT[Id, S, A]. You need to use the lift[M[_]] function defined on StateT to lift StateT[Id, S, A] to StateT[Trampoline, S, A].
def eval(k: Int): MTrans[Int] = {
for {
state <- get[IState].lift[Trampoline].liftM[MTransT]
_ <- put(state.copy(s = (state.s + 1) % k)).lift[Trampoline].liftM[MTransT]
} yield (k + 1)
}
def evalCond(): MTrans[Boolean] = {
for {
state <- get[IState].lift[Trampoline].liftM[MTransT]
} yield (state.s != 0)
}
Finally, calling .run(IState(1)) now results in Trampoline[(IState, String \/ Unit)]. You must additionally run this as well.
eval(k).whileM_(evalCond()).run(IState(1)).run
I have the following code:
type foo= List[bar]
def emtfoo= List[bar]()
def permute(s1:Set[foo],s2:Set[foo]):Set[foo]={
for{
x<-s1
y<-s2
}yield permutatefoo(x,y,e,emtfoo)
def permutatefoo(l1:foo,l2:foo,sofar:foo):Set[foo]={
if (l1.equals (emtfoo)) {
Set{sofar:+l2}
}
else {
combine(permutatefoo(l1.drop(1),l2,l1.take(1):::sofar),
permutatefoo(l1,l2.drop(1),l2.take(1):::sofar))
}
}
def combine(s1:Set[foo],s2:Set[foo]):Set[foo] =
for {
x <- s1
y<- s2
} yield x ::: y
Which should be fairly straightforward code to permutate 2 sets of lists into a single set which has all possible permutations of both lists in order with no element appearing in front of an element in wasn't in front of in the list itself (so if we have list a = 1,2,3 and list b =a,b,c then it should return the Set{1,a,2,b,3,c-1,2,a,3,b,c-a,1,2,3,b,c ext.}).
However my code generates a few errors type mistmaches around the line.
{Set{sofar:+l2}}
and
x<-s1
Does anybody know how to fix this?
I'm not sure I grok all your code, but a few things I see are:
1:
{Set{sofar:+l2}} // should probably be Set(sofar ++ l2)
// as it seems you just want to concatenate sofar and l2
// which are both List[bar] (so your return value is a Set[foo]
// i.e. a Set[List[bar]] as the signature for
// permutatefoo requests
:+ is an extractor (see the doc) and it's not supposed to be used in that way
2:
if (l1.equals (emtfoo)) // you should also check against ls.equals(emtfoo)
// as you're also dropping elements from l2
// in permutatefoo(l1,l2.drop(1),l2.take(1):::sofar))
3:
the return type for permute is wrong. The way you defined it, it returns a Set[Set[foo]] instead of a Set[foo]. I'm not sure I understand what you want it to do, but if you fix the return type it should at least type-check.
This is a version of your code that compiles. I'm not saying it works (as I said, I'm not sure I understand what all the expected inputs and outputs for your program should be), but it compiles.
type bar=Int
type foo= List[bar]
def emtfoo= List[bar]()
def combine(s1:Set[foo],s2:Set[foo]) =
for{
x <- s1
y <- s2
} yield x ++ y
def permutatefoo(l1:foo, l2:foo, sofar:foo): Set[foo]={
if (l1.equals (emtfoo) || l2.equals (emtfoo)) {
Set(sofar ++ l2)
}
else
{
combine(permutatefoo(l1.drop(1),l2,l1.take(1) ++ sofar),
permutatefoo(l1,l2.drop(1),l2.take(1) ++ sofar))
}
}
def permute(s1:Set[foo],s2:Set[foo]) : Set[Set[foo]] = {
for {
x <- s1
y <- s2
} yield permutatefoo(x,y,emtfoo)
}
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.