2010-11-20 62 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