Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can GADTs (or existentials) without constraints be compiled as tight as untyped ordinary ADTs?

Suppose I have some ADT, like

data Foo = Foo !Int
         | Bar (Int->Int) Foo

Now say I want to impose some kind of extra type safety, getting rid of the "magic number type":

{-# LANGUAGE GADTs #-}

newtype Intey a = Intey { getIntey :: Int }

data Foo' a where
   Foo :: !(Intey a) -> Foo' a
   Bar :: (Intey a -> Intey b) -> Foo' a -> Foo' b

Since b is just a phantom argument within the constructor, has no constraints or anything else, it is basically meaningless – except for the type checker. Can it therefore compile down to the same as Foo, without any performance etc. cost?

like image 541
leftaroundabout Avatar asked Apr 15 '14 09:04

leftaroundabout


1 Answers

You'd need to look at the Core to be absolutely sure, but in general:

  • newtype has no runtime cost compared to the underlying type. However something like map getIntey will still traverse the list doing nothing.

  • Types and type parameters themselves are erased during compilation so should also have no runtime cost - this is one of the advantages of static typing. It's only if you use a type class that a runtime value might be passed around.

So in most cases you can expect the same performance, but you may need to be a little careful about operations on containers like lists.

If you restrict yourself to GHC 7.8, then the new coerce function can help with that too.

like image 88
GS - Apologise to Monica Avatar answered Sep 28 '22 00:09

GS - Apologise to Monica