Проверьте, создает ли type экземпляр класса typeclass в GHCI [дубликат]


На этот вопрос уже есть ответ здесь:

Есть ли способ, чтобы задать г Если тип создает typeclass? Я дурачился с оператором ^^ и набрал:

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

Очень полезно. Затем я захотел узнать, может ли рациональное порождать дробное. Я нашел рациональное на Хугл, разыменованный на отношение и, наконец, найденный:

Integral a => Fractional (Ratio a)

Было ли более простой способ? Что-то вроде:

:listypeclasses Rational

Или

:listinstances Fractional
2 2

2 ответа:

Вы хотите :info, который также может быть сокращен :i. Используйте :info <type> для перечисления экземпляров этого типа или :info <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 выше является произвольным, вы можете использовать любой другой тип вместо этого.)