Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How exactly do type synonyms work?

How does it come, that the following type checks

{-# LANGUAGE RankNTypes #-}
module Main where

class Foo a where


type FunFoo = (Foo a) => a -> IO ()

data Bar = Bar {
  funFoo :: FunFoo
}

setFunFoo :: FunFoo -> Bar -> Bar
setFunFoo action bar = bar {funFoo = action}

but when changing the type signature off setFunFoo to

setFunFoo :: ((Foo a) => a -> IO ()) -> Bar -> Bar

it does not? Is there a way to express the above code without the type synonym FunFoo?

like image 429
user514233 Avatar asked Nov 20 '10 05:11

user514233


People also ask

What is a type synonym?

Some common synonyms of type are character, description, kind, nature, and sort.

What are synonyms for work?

vocation. walk. line of business. métier. nine-to-five.

What type of word is synonym?

A synonym is a word, morpheme, or phrase that means exactly or nearly the same as another word, morpheme, or phrase in a given language. For example, in the English language, the words begin, start, commence, and initiate are all synonyms of one another: they are synonymous.


1 Answers

You need to add an explicit forall like so:

setFunFoo :: (forall a. (Foo a) => a -> IO ()) -> Bar -> Bar

The reason for this is because you want the scope of the type variable a to be limited to the type of the first argument to setFunFoo. Without the explicit forall, the desugared type is this:

setFunFoo :: forall a. ((Foo a) => a -> IO ()) -> Bar -> Bar
like image 60
Tom Crockett Avatar answered Oct 06 '22 12:10

Tom Crockett