[Haskell-cafe] It matters how Type Synonyms are defined?

Simon Peyton-Jones simonpj at microsoft.com
Fri Feb 2 17:58:55 EST 2007


Type synonyms are like type level functions.  So long as they are fully applied, the type checker can treat them like macros, and expand them at compile time.  But if they are only partially applied, it can't.  Allowing full functions at the type level makes type inference practically impossible, so it's banned.

In your case, the definition
        type T = S Int
and
        type T a = S Int a
might reasonably be considered equivalent, since eta reduction can turn the latter into the former.  GHC could do automatic eta reduction, but people don't write such type synonyms very much (I think), so it doesn't.

Simon

| -----Original Message-----
| From: haskell-cafe-bounces at haskell.org [mailto:haskell-cafe-bounces at haskell.org] On Behalf Of
| Bryan Burgers
| Sent: 02 February 2007 22:18
| To: haskell-cafe at haskell.org
| Subject: [Haskell-cafe] It matters how Type Synonyms are defined?
|
| Today, I was plugging away on a program and I ran into a problem. It
| seems that ErrorT can or can not take a type synonym as its monad,
| depending on how the type synonym was defined. For example, consider
| this GHCi interactive run:
|
| > :k Maybe
| Maybe :: * -> *
| > let { a :: ErrorT String Maybe Bool; a = undefined }
| > :t a
| a :: ErrorT String Maybe Bool
|
| > :k State (Scope VVar)
| State (Scope VVar) :: * -> *
| > let { a :: ErrorT String (State (Scope VVar)) Bool; a = undefined }
| > :t a
| a :: ErrorT String (State (Scope VVar)) Bool
|
| ScopeState is defined in a file as:
| > type ScopeState a = State (Scope VVar) a
|
| > :k ScopeState
| ScopeState :: * -> *
| > let { a :: ErrorT String ScopeState Bool; a = undefined }
|
| <interactive>:1:6:
|     Type synonym `ScopeState' should have 1 argument, but has been given 0
|     In the type signature: a :: ErrorT String ScopeState Bool
|
| Now, I was going to ask something like, "How can I define my type
| synonym so I can do this," but I figured out while writing this email
| that if I define ScopeState a different way:
| > type ScopeState = State (Scope VVar)
|
| > :k ScopeState
| ScopeState :: * -> *
| > let { a :: ErrorT String ScopeState Bool; a = undefined }
| > :t a
| a :: ErrorT String ScopeState Bool
|
| So, my new question is: Why does it matter how ScopeState is defined?
|
| Bryan Burgers
| _______________________________________________
| Haskell-Cafe mailing list
| Haskell-Cafe at haskell.org
| http://www.haskell.org/mailman/listinfo/haskell-cafe


More information about the Haskell-Cafe mailing list