2010-11-20 23 views
7

它是如何來的,下列類型檢查類型同義詞究竟如何工作?

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

但改變類型簽名關閉setFunFoo到

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

當它不?有沒有一種方法來表達上面的代碼沒有類型同義詞FunFoo?

+3

你確定你打算使用rank-n類型嗎?對於有人詢問類型同義詞如何工作,這是一個相當先進的主題。 – 2010-11-20 06:17:59

回答

7

您需要添加一個明確的forall像這樣:

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

這樣做的原因是因爲你想要的類型變量a的範圍僅限於第一個參數setFunFoo的類型。沒有明確的forall,desugared類型是這樣的:

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