hmemcpy / milewski-ctfp-pdf

Bartosz Milewski's 'Category Theory for Programmers' unofficial PDF and LaTeX source
https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/
Other
10.91k stars 581 forks source link

Incorrect Scala code for OneOfThree type example in Section 6.3 Sum Types #179

Closed jasonrute closed 5 years ago

jasonrute commented 5 years ago

In the section 6.3 Sum Types, there is an example called OneOfThree with the following Scala code:

sealed trait OneOfThree[A, B, C]
final case class Sinistral[A](v: A) extends OneOfThree[A, Nothing, Nothing]
final case class Medial[B](v: B) extends OneOfThree[Nothing, B, Nothing]
final case class Dextral[C](v: C) extends OneOfThree[Nothing, Nothing, C]

While this will compile, it won't work. It is impossible (at least without type coercion) to get a type of, say, OneOfThree[Int, Int, Int]. The solution is to make the type parameters covariant by adding +s to the first line as follows:

sealed trait OneOfThree[+A, +B, +C]

This would agree with the examples of Either[+A,+B] and Option[+A] in the same section of the book, and it is idiomatic Scala.

(There is another possible solution which is to change all the other lines to something like final case class Sinistral[A, B, C](v: A) extends OneOfThree[A, B, C], but that would be unwieldy in practice and be different from the other examples in the book.)

hmemcpy commented 5 years ago

Isn't variance/subtyping fun :) This is a great suggestion, this is how Scala ADTs are typically defined. I would really appreciate a PR for this. Thanks!

jasonrute commented 5 years ago

Sure. I'll make a PR for this file (https://github.com/hmemcpy/milewski-ctfp-pdf/blob/master/src/content/1.6/code/scala/snippet22.scala) later today or tomorrow.

hmemcpy commented 5 years ago

Fixed in #180.