Search code examples
haskellnewtype

multi-parameter newtype faked with a tuple?


This is a dumb question that's been bugging me for a bit. Why can't I write a newtype with multiple parameters,

newtype A = A Int Int

while the tuple version is just fine?

newtype A = A (Int, Int)

the former is much nicer in things like pattern matching.


Solution

  • newtype A = A Int creates a type isomorphic to Int. That is, it behaves exactly like Int w.r.t. e.g. bottom, but under a different name.

    This is in contrast with data A = A Int which creates a lifted type that behaves differently from Int. There's another value added that is not in Int: A undefined (which is distinct from undefined::A).

    Now, newtype A = A (Int, Int) creates a type isomorphic to (Int, Int). Which is, incidentally, exactly exactly what data A = A Int Int does.

    So if we admit newtype A = A Int Int as being equivalent to newtype A = A (Int, Int), what do we have? newtype A = A Int Int is equivalent to newtype A = A (Int, Int) which is equivalent to data A = A Int Int.

    newtype A = A Int Int is equivalent to data A = A Int Int (so newtype is redundant in this case), but

    newtype A = A Int is not equivalent to data A = A Int (which is the whole point of having newtype in the first place).

    So we must conclude that newtype A = A Int Int being equivalent to newtype A = A (Int, Int) creates redundancy and inconsistency, and we're better off not allowing it.

    There's probably no way to give newtype A = A Int Int some other meaning which is free from these inconsistencies (or else it would be found and used I suppose ;)