Haskell RankNTypes

示例

想象一下以下情况:

foo :: Show a => (a -> String) -> String -> Int -> IO ()
foo show' string int = do
   putStrLn (show' string)
   putStrLn (show' int)

在这里,我们希望传入一个将值转换为String的函数,将该函数同时应用于string参数和int参数,并同时打印它们。在我看来,这没有理由失败!我们有一个函数可以处理传入的两种参数。

不幸的是,这不会输入检查!GHCa根据其在功能主体中的首次出现来推断类型。也就是说,一旦我们点击:

putStrLn (show' string)

GHC会推断show' :: String -> String,因为string是String。尝试时它会炸毁show' int。

RankNTypes相反,您可以按如下方式编写类型签名,以量化满足该show'类型的所有函数:

foo :: (forall a. Show a => (a -> String)) -> String -> Int -> IO ()

这是2级多态:我们断言,该show'功能必须为所有工作的a小号我们的功能,和以前的实现,现在的作品。

该RankNTypes扩展允许forall ...在类型签名中任意嵌套块。换句话说,它允许秩N多态性。