检查类型是否在 GHCI 中实例化类型类

Check if type instantiates a typeclass in GHCI

有没有办法询问 GHCi 类型是否实例化了类型类?我在玩 ^^ 运算符并输入:

Prelude> :type (^^)
(^^) :: (Integral b, Fractional a) => a -> b -> a

很有用。然后我想知道Rational是否实例化了Fractional。我在 Hoogle 上找到了 Rational,取消了对 Ratio 的引用,最后发现:

Integral a => Fractional (Ratio a)

有没有更简单的方法?类似于:

:listypeclasses Rational

:listinstances Fractional

你要:info,也可以简写:i。使用 :info <type> 列出该类型的实例或使用 :info <class> 列出该 class.

的实例

Rational的情况下,由于是类型别名,:info不会直接列出实例。然而,它 告诉你它是一个类型别名,你可以通过在它别名的类型上使用 :info 来跟进:

ghci> :info Ratio
data Ratio a = !a :% !a     -- Defined in ‘GHC.Real’
instance Eq a => Eq (Ratio a) -- Defined in ‘GHC.Real’
instance Integral a => Ord (Ratio a) -- Defined in ‘GHC.Real’
instance Show a => Show (Ratio a) -- Defined in ‘GHC.Real’
instance (Integral a, Read a) => Read (Ratio a)
  -- Defined in ‘GHC.Read’
instance Integral a => Enum (Ratio a) -- Defined in ‘GHC.Real’
instance Integral a => Fractional (Ratio a)
  -- Defined in ‘GHC.Real’
instance Integral a => Num (Ratio a) -- Defined in ‘GHC.Real’
instance Integral a => Real (Ratio a) -- Defined in ‘GHC.Real’
instance Integral a => RealFrac (Ratio a) -- Defined in ‘GHC.Real’

这里有一个方法:

> :set -XFlexibleContexts
> :t undefined :: (Fractional Rational) => Int

<interactive>:1:14: warning: [-Wsimplifiable-class-constraints]
    • The constraint ‘Fractional Rational’
        matches an instance declaration
      instance Integral a => Fractional (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      This makes type inference for inner bindings fragile;
        either use MonoLocalBinds, or simplify it using the instance
    • In an expression type signature: (Fractional Rational) => Int
      In the expression: undefined :: (Fractional Rational) => Int
undefined :: (Fractional Rational) => Int :: Int

这只是一个警告,所以实例存在。

> :t undefined :: (Fractional Bool) => Int

<interactive>:1:1: error:
    No instance for (Fractional Bool)
      arising from an expression type signature

这是一个错误,所以没有实例。

(上面的Int是任意的,你可以用其他类型代替。)