类型同义词究竟是如何工作的?

use*_*233 7 haskell types type-systems higher-rank-types

如何进行,以下类型检查

{-# 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}
Run Code Online (Sandbox Code Playgroud)

但是当将setFunFoo的类型签名更改为

setFunFoo :: ((Foo a) => a -> IO ()) -> Bar -> Bar
Run Code Online (Sandbox Code Playgroud)

它不是?有没有一种方法来表达上面的代码没有类型同义词FunFoo?

Tom*_*ett 7

你需要forall像这样添加一个显式:

setFunFoo :: (forall a. (Foo a) => a -> IO ()) -> Bar -> Bar
Run Code Online (Sandbox Code Playgroud)

这是因为您希望将type变量的范围a限制为第一个参数的类型setFunFoo.没有明确的forall,desugared类型是这样的:

setFunFoo :: forall a. ((Foo a) => a -> IO ()) -> Bar -> Bar
Run Code Online (Sandbox Code Playgroud)