3 ms·
I can't speak about OCaml, but Haskell doesn't have subtypes. That's where a lot of the complexity of Scala comes from as well as being a source of annoying bug
by yummyfajitas 12y ago
I can't speak about OCaml, but Haskell doesn't have subtypes. That's where a lot of the complexity of Scala comes from as well as being a source of annoying bugs:
def f(x: Int) = if (x % 2 == 0) { x } else { None }
(This compiles, but the type of `f` is not `f: Int => Option[Int]`.)
[edit: the bug is not in the scala compiler, the bug is in my code - I almost certainly did not want `f` to have type `Int => Any`. My phrasing, now edited, was misleading. ]
- kod 12y agoThat is not a bug. That is subtype inference working correctly. If you (mistakenly) expected the return type of f to be Option[Int], say so, and you'll get a compile time error telling you about your mistake: scala> def f(x: Int): Option[Int] = if (x % 2 == 0) { x } else { None } <console>:7: error: type mismatch; found : Int required: Option[Int] def f(x: Int): Option[Int] = if (x % 2 == 0) { x } else { None }
- azth 12y agoscala> def f(x: Int) = if (x % 2 == 0) { x } else { None } f: (x: Int)Any Which is expected. The only shared type between both branches of the `if` expression is `Any`.
- zak_mc_kracken 12y agoThis is correct given Scala's limitation: the only common supertype between Int and Option is Any. A language that supports union types (e.g. Ceylon) will type this expression as Int|Option[Int], which is as specific as you can get.
- axiomabsolute 12y agoI believe Ceylon will actually further refine Int | Option[Int] to simply Option[Int]. Option[Int] is simply an alias to the type Int | Null, so Int | Option[Int] would become Int | Int | Null after replacement, which simplifies to Int | Null since Int | Int is equivalent to just Int.