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 的情况下表达上述代码?

4

1 回答 1

7

您需要forall像这样添加显式:

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

这样做的原因是因为您希望将类型变量的范围a限制为 的第一个参数的类型setFunFoo。没有显式forall,脱糖类型是这样的:

setFunFoo :: forall a. ((Foo a) => a -> IO ()) -> Bar -> Bar
于 2010-11-20T05:53:52.897 回答