如何进行,以下类型检查
{-# 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?
答案 0 :(得分:7)
您需要添加一个明确的forall
,如下所示:
setFunFoo :: (forall a. (Foo a) => a -> IO ()) -> Bar -> Bar
之所以这样,是因为您希望将类型变量a
的范围限制为setFunFoo
的第一个参数的类型。没有明确的forall
,desugared类型是这样的:
setFunFoo :: forall a. ((Foo a) => a -> IO ()) -> Bar -> Bar