2010-11-20 9 views
7

Wie kommt es, dass die folgenden TypprüfungenWie funktionieren Synonyms genau?

{-# 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} 

aber wenn die Art Signatur off setFunFoo zu

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

es nicht zu ändern? Gibt es eine Möglichkeit, den obigen Code ohne das Synonym FunFoo auszudrücken?

+3

Sind Sie sicher, dass Sie beabsichtigen, Rang-n-Typen zu verwenden? Das ist ein relativ fortgeschrittenes Thema für jemanden, der fragt, wie Typensynonyme funktionieren. –

Antwort

7

Sie benötigen eine explizite forall wie so hinzuzufügen:

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

Der Grund dafür ist, dass Sie den Umfang des Typs Variable a beschränkt sein auf die Art des ersten Arguments zu setFunFoo wollen. Ohne den expliziten Code forall lautet der entartete Typ:

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