4

We can define type synonyms with arguments and this works fine when used with actual types:

type MyType t = t String String

data Test a b = Test a b

f :: MyType Test
f = undefined

main = undefined

Compiling this results in no errors:

$ghc --make test.hs                                           
[1 of 1] Compiling Main             ( test.hs, test.o )                                          
Linking test ...   

However this doesn't work when Test is a type synonym:

type MyType t = t String String

data Test a b = Test a b

type Test' a b = Test a b

f :: MyType Test'
f = undefined

main = undefined

Which gives the following error:

$ghc --make test.hs
[1 of 1] Compiling Main             ( test.hs, test.o )

test.hs:7:6:
    Type synonym Test' should have 2 arguments, but has been given none
    In the type signature for `f': f :: MyType (Test')

What puzzles me is that Test' is being applied to two arguments, so why is GHC complaining that I didn't pass the arguments?

Shouldn't type synonym be completely transparent and impossible to distinguish from other kind of types?

Is there any way to achieve the expected behaviour?

Bakuriu
  • 98,325
  • 22
  • 197
  • 231
  • 2
    http://stackoverflow.com/a/4923883/477476 – Cactus Jul 22 '14 at 07:38
  • possible duplicate of [Why doesn't TypeSynonymInstances allow partially applied type synonyms to be used in instance heads?](http://stackoverflow.com/questions/4922560/why-doesnt-typesynonyminstances-allow-partially-applied-type-synonyms-to-be-use) – huon Jul 22 '14 at 07:52
  • 2
    @dbaupp My question isn't about GHC extensions nor instance declarations. The fact that the answer may be the same does **not** imply that the *questions* are duplicates. Also the answers to that question don't address the second part of my question (how to allow that kind of code), which I just discovered that *is* possible using `LiberalTypeSynonyms` (which is *in contrast* to those answers). – Bakuriu Jul 22 '14 at 08:05
  • @Cactus That answer & question are about *partial* type synonym application. My question is about **total** type synonym application using other type synonyms (`MyType Test'` results in a *total* application of `Test'` after expansion). Their are completely different things, and in fact the answers are different since you can solve the latter using a very simple extension, while the former would make the type system undecidable. – Bakuriu Jul 22 '14 at 08:21

1 Answers1

12

According to the Haskell report type synonyms cannot be partially applied:

Type constructor symbols T introduced by type synonym declarations cannot be partially applied; it is a static error to use T without the full number of arguments.

In particular this is checked before expanding the type synonyms, this means that in the expression:

MyType Test'

The check is performed before expanding MyType and hence Test' results partially applied.

However, it is possible to achieve that behaviour using GHC LiberalTypeSynonyms extension. This extension treats type synonyms as macros, which are expanded without any check and afterwards the type checker will see whether the type synonym was partially applied.

Kind inference is still done before type synonym expansion.

Note that type synonyms cannot be partially applied even in this case, i.e. something such as:

Test' Int

is still an error. However you now can use type synonyms to totally apply other type synonyms without receiving errors.

Allowing partial application of type synonyms would make type inference undecidible, so it's not possible to easily extend the type system in that direction.

Bakuriu
  • 98,325
  • 22
  • 197
  • 231