Last active
June 10, 2020 10:14
-
-
Save aSapien/74aae638c9ab6f201eaf38b51d9decfb to your computer and use it in GitHub Desktop.
ERROR: Result type in structural refinement may not refer to a user-defined value class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Example extends App { | |
/** | |
* Structural Types | |
* */ | |
// define a type based on its structure. Doesn't have to be named. | |
type StructuralToLong = { def toLong: Long } | |
// Use this type: | |
def workToLong1(a: StructuralToLong): Long = a.toLong // using named type | |
def workToLong2(a: { def toLong: Long }): Long = a.toLong // using structure directly | |
trait ToLongable { | |
def toLong: Long = -1L | |
} | |
workToLong1(new ToLongable {}) | |
workToLong2(new ToLongable {}) | |
/** | |
* Value Classes (common example, extension methods) | |
* */ | |
implicit class Foo(val s: String) extends AnyVal { | |
def fooString: String = s"foo $s" | |
} | |
"bar".fooString | |
/** | |
* Value classes limitation: "structural types cannot use value classes in method parameter or return types" | |
* [[https://docs.scala-lang.org/overviews/core/value-classes.html#examples-of-limitations]] | |
*/ | |
// class Value(val x: Int) extends AnyVal | |
// object Usage { | |
// def anyValue(v: { def value: Value }): Value = | |
// v.value | |
// } | |
/* | |
Struct.scala:3: error: Result type in structural refinement may not refer to a user-defined value class | |
def anyValue(v: { def value: Value }): Value = | |
^ | |
*/ | |
/** | |
* Singleton types | |
* [[https://www.scala-lang.org/files/archive/spec/2.11/03-types.html#singleton-types]] | |
* | |
* Every stable type not only belongs to a type family (such as the trait or class), but also to a singleton type of its own. | |
* Only the same reference can be assigned to it. | |
* | |
* Example source | |
* [[https://blogs.oracle.com/sundararajan/misunderstaning-scalas-singleton-types]] | |
*/ | |
val s = "hello" // s: String = hello | |
val x: s.type = s // x: s.type = hello | |
// val p: s.type = "hello" // error: type mismatch | |
/** | |
* Structural refinement | |
*/ | |
trait Ctx | |
// What's the type of ctxFoo? | |
val ctxFoo = new Ctx { | |
def foo: String = "foo" | |
} | |
ctxFoo.foo | |
// `ctxFoo`s singleton type has been "structurally refined" | |
ctxFoo.isInstanceOf[Ctx with ({ type T = { def foo: String} })#T] // true | |
/** | |
* specs2+wio problem manifestation: | |
* | |
* WIO is a value class on top of ZIO: | |
* final class WIO[+A](val zio: WTask[A]) extends scala.AnyVal {...} | |
* | |
* the spec is a structural refinement of the singleton type of the `ctx` (Scope) trait: | |
* | |
* "foobar" should { | |
* "foo with trait" in new Ctx { | |
* val someWio: WIO[Any] = ??? // Illegal | |
* } | |
* | |
* "foo without trait" in { | |
* val someWio: WIO[Any] = ??? // Legal | |
* } | |
* } | |
* | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment