Skip to content

Instantly share code, notes, and snippets.

@aSapien
Last active June 10, 2020 10:14
Show Gist options
  • Save aSapien/74aae638c9ab6f201eaf38b51d9decfb to your computer and use it in GitHub Desktop.
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
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