Search code examples
scalahaskellwrapperprimitive-typesnewtype

Why are value classes restricted to AnyVal?


As far as I understand value classes in Scala are just there to wrap primitive types like Int or Boolean into another type without introducing additional memory usage. So they are basically used as a lightweight alternative to ordinary classes.

That reminds me of Haskell's newtype notation which is also used to wrap existing types in new ones, thus introducing a new interface to some data without consuming additional space (to see the similarity of both languages consider for instance the restriction to one "constructor" with one field both in Haskell and in Scala).

What I am wondering is why the concept of introducing new types that get inlined by the compiler is not generalized to Haskell's approach of having zero-overhead type wrappers for any kind of type. Why did the Scala guys stick to primitive types (aka AnyVal) here?

Or is there already a way in Scala to also define such wrappers for Scala.AnyRef types?


Solution

  • They're not limited to AnyVal.

    implicit class RichOptionPair[A,B](val o: Option[(A,B)]) extends AnyVal {
      def ofold[C](f: (A,B) => C) = o map { case (a,b) => f(a,b) }
    }
    
    scala> Some("fish",5).ofold(_ * _)
    res0: Option[String] = Some(fishfishfishfishfish)
    

    There are various limitations on value classes that make them act like lightweight wrappers, but only being able to wrap primitives is not one of them.