如何在type关键字中使用typeclass?

时间:2018-07-18 00:09:51

标签: haskell

我有一个功能

logger :: ToJSON a => String -> a -> IO ()

我想为此类型签名创建一个别名

type Logger = ToJSON a => String -> a -> IO ()

这样我可以使用相同的类型签名来做更多的功能:

logger :: Logger

simpleLogger :: Logger

但是我遇到一个错误:

    • Illegal qualified type: ToJSON a => String -> a -> IO ()
      Perhaps you intended to use RankNTypes or Rank2Types
    • In the type synonym declaration for ‘Logger’

1 个答案:

答案 0 :(得分:1)

GHC需要使用RankNTypes扩展名才能显示具有约束的类型

  1. 在类型同义词的定义中:

    type A x = C x => x -> Y
    
  2. 在新类型或数据类型声明的字段中,或

    newtype B x = B (C x => x -> Y)
    data D x = D (C x => x -> Y)
    
  3. 在箭头的左侧。

    f :: (C x => x -> Y) -> Z
    

这似乎有点令人惊讶(对我而言确实如此),因为这些类型实际上都是等级1。但是,有人告诉我,这些类型的推理要求实际上与高等级类型的推理要求非常相似。在这两种情况下,都可能需要推断一个论点。对于较高级别的类型,这是类型参数。对于受约束的类型,这是一个字典参数。

如果要编写Haskell模块,请添加

{-# language RankNTypes #-}

到源文件的最顶部(在module行之前)。如果您使用的是GHCi,请运行

ghci -XRankNTypes

或键入

:set -XRankNTypes

在GHCi提示符下。