Scala path dependent return type from parameter - scala

In the following code using 2.10.0M3 in Eclipse plugin 2.1.0 for 2.10M3. I'm using the default setting which is targeting JVM 1.5
class GeomBase[T <: DTypes] {
abstract class NewObjs {
def newHex(gridR: GridBase, coodI: Cood): gridR.HexRT
}
class GridBase {
selfGrid =>
type HexRT = HexG with T#HexTr
def uniformRect (init: NewObjs) {
val hexCood = Cood(2 ,2)
val hex: HexRT = init.newHex(selfGrid, hexCood)// won't compile
}
}
}
Error message:
Description Resource Path Location Type type mismatch;
found: GeomBase.this.GridBase#HexG with T#HexTr
required: GridBase.this.HexRT (which expands to) GridBase.this.HexG with T#HexTr GeomBase.scala
Why does the compiler think the method returns the type projection GridBase#HexG when it should be this specific instance of GridBase?
Edit transferred to a simpler code class in responce to comments now getting a different error message.
package rStrat
class TestClass {
abstract class NewObjs {
def newHex(gridR: GridBase): gridR.HexG
}
class GridBase {
selfGrid =>
def uniformRect (init: NewObjs) {
val hex: HexG = init.newHex(this) //error here
}
class HexG {
val test12 = 5
}
}
}
.
Error line 11:Description Resource Path Location Type
type mismatch; found : gridR.HexG required: GridBase.this.HexG
possible cause: missing arguments for method or constructor TestClass.scala /SStrat/src/rStrat line 11 Scala Problem
Update I've switched to 2.10.0M4 and updated the plug-in to the M4 version on a fresh version of Eclipse and switched to JVM 1.6 (and 1.7) but the problems are unchanged.

logged as SI-5958 - substitute this in dependent method type

This now works as of 2.10.0M7. The bug has been fixed.
val hex: HexRT = init.newHex(selfGrid, hexCood) //now compiles and runs correctly

Related

Implicit parameter need Type annotation to compile

Here is my test code :
object ImplicitTest {
import JoesPrefs._
Greeter.greet("Joe") // could not find implicit value for parameter prompt:
}
class PreferredPrompt(val preference: String)
object JoesPrefs {
implicit val prompt = new PreferredPrompt("Yes, master> ")
}
object Greeter {
def greet(name: String)(implicit prompt: PreferredPrompt) = {
println("Welcome, " + name + ". The system is ready.")
println(prompt.preference)
}
}
I use scala 2.11.12, don't know why this implicit not work until add type annotation to val :
object JoesPrefs {
implicit val prompt: PreferredPrompt = new PreferredPrompt("Yes, master> ")
}
So, the exact internal are a bit wild, but basically it boils down to the compilation order of the code.
When you add the type annotation, the val is "compiled and put in scope" sooner than when you do not, and it becomes available to resolve in ImplicitTest.
Funnily (at least for me ^^), you can also move ImplicitTest to be on a line of code after the JoesPref object (or move it to its own file), it will compile without the type annotation.

Scala 2.10 "No implicit view available" error on type parameter that asks for a view

I have reduced this example from something encountered in a much larger project; the fundamental issue seems to be that Scala 2.10 has weird or possibly broken handling of view constraints:
trait Nameish {
def name: String
}
abstract class Namer[A <% Nameish](e: Class[A]) {
def doNameThing(x: A) = println("argument is named " + x.name)
}
class SubNamer[A <% Nameish](e: Class[A]) extends Namer(e) {
}
object TestViews extends App {
import scala.language.implicitConversions
implicit def nameStr(x: String): Nameish = new StringNamer(x);
class StringNamer(x: String) extends Nameish {
def name = x
}
println(new SubNamer(classOf[String]).doNameThing("foo"))
}
When I try to compile this, in scala 2.10 I get the errors:
TestViews.scala:8: error: No implicit view available from A => Nameish.
class SubNamer[A <% Nameish](e: Class[A]) extends Namer(e) {
^
TestViews.scala:18: error: value doNameThing is not a member of SubNamer[String]
println(new SubNamer(classOf[String]).doNameThing("foo"))
^
two errors found
Note that Scala 2.11 is fine with this code.
Unfortunately, re-tooling this code to a newer scala version would make this task explode in size. I need to find a way to make the existing scala accept a class hierarchy with a type parameter that has a view constraint.
Another attempt at a way around this has uncovered a different scala-2.10-only error case:
trait Nameish {
def name: String
}
abstract class Namer[A](e: Class[A])(implicit view: A => Nameish) {
def doNameThing(x: A) = println("argument is named " + x.name)
}
class SubNamer[A](e: Class[A])(implicit view: A => Nameish) extends Namer(e)(view) {
}
object TestViews extends App {
import scala.language.implicitConversions
implicit def nameStr(x: String): Nameish = new StringNamer(x);
class StringNamer(x: String) extends Nameish {
def name = x
}
println(new SubNamer(classOf[String]).doNameThing("foo"))
}
This is just replacing the view constraints with implicit arguments.
With this code, it again compiles just fine with Scala 2.11, but on Scala 2.10:
TestViews.scala:8: error: `implicit' modifier cannot be used for top-level objects
class SubNamer[A](e: Class[A])(implicit view: A => Nameish) extends Namer(e)(view) {
^
one error found
I don't understand what's going on here: I'm not trying to declare an implicit object, I'm trying to declare that the class takes an implicit parameter. Why is it fine for the first class, but not the second one?
Adding parameter type parameter A to Namer (in the Subnamer inheritance) worked for me (Scala version 2.10.7):
class SubNamer[A <% Nameish](e: Class[A]) extends Namer[A](e)
By the way your example without modification worked for me only from the Scala version 2.11.5.
Hope this helps.

Why Scala Enumeration does not work in Apache Zeppelin but it works in maven

Enumeration works as expected when I use it in a maven project(with the same Scala version).
object t {
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
def main(args: Array[String]) = f(DashStyle.Solid)
}
But when it runs in Apache Zeppelin(Zeppelin 0.6, Spark 1.6, Scala 2.10, Java 1.8)
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
f(DashStyle.Solid)
It reports the following error even it says found and required type is exactly the same
<console>:130: error: type mismatch;
found : DashStyle.Value
required: DashStyle.Value
f(DashStyle.Solid)
Why and how should I use it?
I figured out the trick to solve this issue.
In Apache Zeppelin (or Scala REPL). In order to use Enumeration or sealed&object, it should be wrapped in object but not directly define on the root scope.
The reason why it works in maven is that I already put it into an object.
Define enumeration in an object in a Zeppelin paragraph
object t {
object DashStyle extends Enumeration {
val Solid,ShortDash = Value
}
def f(style: DashStyle.Value) = println(style)
}
Then use it in a Zeppelin paragraph
import t._
f(DashStyle.Solid)

Scala: "No manifest available for type T"

I am working on a Lift project with mixed Scala and Java code.
On the Java side, I have the following relevant items:
interface IEntity
interface IDAO<T extends IEntity> {
void persist(T t);
}
On the Scala side, I have the following:
abstract class Binding[T <: IEntity] extends NgModel {
def unbind: T
}
class BasicService[E <: IEntity](serviceName: String, dataAccessObject: IDAO[E]) {
def render = renderIfNotAlreadyDefined(
angular.module("myapp.services")
.factory(serviceName,
jsObjFactory()
.jsonCall("persist", (binding: Binding[E]) => { //<---COMPILATION ERROR
try {
dataAccessObject.persist(binding.unbind)
Empty
} catch {
case e: Exception => Failure(e.getMessage)
}
})
)
)
}
This code will not compile. I get the following error at the point indicated above:
No Manifest available for Binding[E].
It is not clear at all to me why this occurs, but I am guessing it has something to do with this being a nested method invocation. The code compiles fine if I declare a member function with Binding[E] as a parameter, for example:
def someFunction(binding: Binding[E] = { // same code as above }
Why does this happen, and how can I work around it?
Turns out this is relatively easily solved by implicitly passing on the manifest for the type in question, either in the constructor or the method itself:
class BasicService[E <: IEntity](serviceName: String, dataAccessObject: IDAO[E])(implicit m: Manifest[Binding[E]]) {
or
def render(implicit m: Manifest[Binding[E]])

Type error when mocking Slick Query using ScalaMock: what does "some other" mean?

I have used Java for several years, however I'm new to Scala and am still trying to figure out its type system. I'm using Scala 2.10.2, Slick 1.0.1, and ScalaMock 2.10-3.0-M4 in Eclipse Scala IDE 3.0.1
I'm trying to mock out Slick in updateNameById using ScalaMock.
def updateNameById(id: Int, input: String, users: RichTable[Object]) = {
users.where(_.id === id).map{ e => e.test }.update(input)
}
abstract class RichTable[T](name: String = "blank")
extends slick.driver.MySQLDriver.simple.Table[T](name) {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def test = column[String]("test")
}
(I'm actually passing in users: RichTable[User] where User has a complex inheritance hierarchy, but I've temporarily removed the uses of User to simplify the example)
users.where returns a scala.slick.lifted.Query, so I try to mock this out as follows
class ModelTest extends FlatSpec with MockFactory {
def test = {
val mockUsers = mock[RichTable[Object]]
// mockQuery definition
val mockQuery = mock[scala.slick.lifted.Query[RichTable[Object],
scala.slick.lifted.NothingContainer#TableNothing]]
(mockUsers.where _).expects(*).returns(mockQuery)
Main.updateNameById(1, "asdf", mockUsers)
}
}
The mockQuery definition gives me these cryptic type errors
type mismatch;
found : scala.slick.lifted.Query[O(in method union),
scala.slick.lifted.NothingContainer#TableNothing]
required: scala.slick.lifted.Query[(some other)O(in method union),
scala.slick.lifted.NothingContainer#TableNothing]
type mismatch;
found : scala.slick.lifted.Query[O(in method unionAll),
scala.slick.lifted.NothingContainer#TableNothing]
required: scala.slick.lifted.Query[(some other)O(in method unionAll),
scala.slick.lifted.NothingContainer#TableNothing]
I have no idea what "O(in method union[all])" vs. "(some other)O(in method union[All])" means, and Google hasn't been any help (it doesn't help matters that "some other" is an extremely generic phrase - googling "scala some other type error" produces pretty much the same results as "scala type error"). Does anybody know what this means and/or how to fix the type error?