Предложенные нефункциональные методы будут иметь тип
floatRadix' :: RealFloat a => Integer
floatDigits' :: RealFloat a => Int
...
Это неоднозначные типы : есть переменная типа a
, но на самом деле она не отображаетсяправо на =>
и, следовательно, не может быть выведено из контекста.Что, в стандартном Haskell, действительно only способ, которым вы можете вывести такую переменную типа: локальные сигнатуры типа также могут быть только для заголовка сигнатуры, но не для ограничения.поэтому, пишете ли вы (floatDigits' :: Int)
или (floatDigits' :: RealFloat Double => Int)
, на самом деле это не сработает - компилятор не может сделать вывод, что вы имеете в виду версию метода instance RealFloat Double
.
class RealFloat' a where
floatDigits' :: Int
instance RealFloat' Double where
floatDigits' = floatDigits (0 :: Double)
*Main> floatDigits' :: Int
<interactive>:3:1: error:
• No instance for (RealFloat' a0)
arising from a use of ‘floatDigits'’
• In the expression: floatDigits' :: Int
In an equation for ‘it’: it = floatDigits' :: Int
*Main> floatDigits' :: RealFloat Double => Int
<interactive>:4:1: error:
• Could not deduce (RealFloat' a0)
arising from a use of ‘floatDigits'’
from the context: RealFloat Double
bound by an expression type signature:
RealFloat Double => Int
at :4:17-39
The type variable ‘a0’ is ambiguous
• In the expression: floatDigits' :: RealFloat Double => Int
In an equation for ‘it’:
it = floatDigits' :: RealFloat Double => Int
ДляПо этой причине Haskell не позволяет вам писать методы с неоднозначным типом.Фактически, попытка скомпилировать класс, как я написал выше, выдает следующее сообщение об ошибке:
• Could not deduce (RealFloat' a0)
from the context: RealFloat' a
bound by the type signature for:
floatDigits' :: forall a. RealFloat' a => Int
at /tmp/wtmpf-file3738.hs:2:3-21
The type variable ‘a0’ is ambiguous
• In the ambiguity check for ‘floatDigits'’
<b>To defer the ambiguity check to use sites, enable AllowAmbiguousTypes</b>
When checking the class method:
floatDigits' :: forall a. RealFloat' a => Int
In the class declaration for ‘RealFloat'’
Однако выделенная строка указывает на расширение GHC, которое говорит: «все в порядке, я знаю, что делаю».Поэтому, если вы добавите {-# LANGUAGE AllowAmbiguousTypes #-}
в начало файла с class RealFloat'
в нем, компилятор примет это.
Какой смысл, когда экземпляр не можетразрешаться при использовании сайта?Ну, это можно на самом деле решить, но только с использованием другого довольно нового расширения GHC :
*Main> :set -XTypeApplications
*Main> floatDigits' @Double
53