Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with my Haskell type synonym?

I have two functions for controlling loops, continue and break:

type Control a = (a -> a) -> a -> a

continue :: Control a
continue = id

break :: Control a
break = const id

Then, I wanted to simplify the Control type synonym. Hence, I wrote:

type Endo a = a -> a

type Control a = Endo (Endo a)

continue :: Control a
continue = id

break :: Control a
break = const id

However, when I tried to further simplify it I got an error:

GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
Prelude> type Endo a = a -> a
Prelude> type Duplicate w a = w (w a)
Prelude> type Control a = Duplicate Endo a

<interactive>:4:1:
    Type synonym ‘Endo’ should have 1 argument, but has been given none
    In the type declaration for ‘Control’

I don't understand why I am getting this error. Perhaps you could enlighten me.

like image 273
Aadit M Shah Avatar asked Jul 30 '15 15:07

Aadit M Shah


2 Answers

As said by Fraser, this kind of stuff can't generally work because type partially applied type synonyms make everything undecidable.

However, if you chuck in the -XLiberalTypeSynonyms extension, GHC will inline the synonyms until it can work out the inference:

Prelude> type Endo a = a -> a
Prelude> type Duplicate w a = w (w a)
Prelude> type Control a = Duplicate Endo a

<‌interactive>:4:1:
    Type synonym ‘Endo’ should have 1 argument, but has been given none
    In the type declaration for ‘Control’
Prelude> :set -XLiberalTypeSynonyms
Prelude> type Control a = Duplicate Endo a
like image 85
leftaroundabout Avatar answered Sep 27 '22 23:09

leftaroundabout


Type synonyms have to be fully applied al all times. You cannot partially apply them.

If you're intent on doing this, you will likely need to newtype it.

like image 43
Fraser Avatar answered Sep 27 '22 23:09

Fraser