Неоднозначность между классом Haskell Num и моим классом, похожим на шоу - PullRequest
4 голосов
/ 17 мая 2011

Я пытаюсь объявить свои собственные данные с соответствующим преобразованием в качестве класса.Мой код выглядит следующим образом:

data SomeData =  SInteger Integer | SElse deriving Show

class Some a where
    toSome :: a -> SomeData

instance Some Int where toSome = SInteger . toInteger

main :: IO ()
main = print $ toSome 3

Но GHC (7.0.3) сердится и говорит:

Ambiguous type variable `a0' in the constraints:
      (Some a0) arising from a use of `toSome'
                at minimal_broken.hs:11:16-21
      (Num a0) arising from the literal `3' at minimal_broken.hs:11:23
    Probable fix: add a type signature that fixes these type variable(s)

Явная подпись типа (например, 3 :: Int) устраняет проблему,но это очень неудобно.
Стандартное «Шоу» работает просто отлично, и в соответствии с руководством оно объявлено точно так же.

Почему стандартное Шоу работает, а мой класс - нет?Я что-то пропустил?

PS: Явный "default (Int)" не разрешает это.

Ответы [ 3 ]

4 голосов
/ 17 мая 2011

Вы правы насчет перегрузки.Это немного сложно.Во-первых, вам придется дать сигнатуру типа, чтобы разрешить числовую перегрузку в вашем примере:

Ambiguous type variable `a0' in the constraints:
  (Some a0) arising from a use of `toSome' at A.hs:11:16-21
  (Num a0) arising from the literal `3' at A.hs:11:23

это означает, как вы заметили, что вам нужно выбрать конкретный тип решения, например, Int.

Так как же работает Show?По волшебству расширенные правила по умолчанию .Show является особенным, и GHCi позволяет некоторым специальным правилам по умолчанию помогать «по умолчанию» типу в аргументах Show to Integer .

Ваш новый класс не является одним из магических классов, которыерасширенная функция по умолчанию знает о, так что, к сожалению, вам нужно будет дать аннотации типа.

1 голос
/ 17 мая 2011

Причина, по которой что-то вроде show 3 работает в первую очередь, связана с правилом по умолчанию, которое выбирает определенный тип, когда существует неопределенность, связанная с классом Num. Причина, по которой он не работает с вашим классом Some, заключается в том, что правило гласит, что все задействованные классы должны быть стандартными классами (т. Е. Из Prelude и т. Д.). Эта последняя часть правила выглядит несколько глупо.

0 голосов
/ 17 мая 2011

проблема: тип 3 равен Num a => a, но ghc нужен конкретный тип для поиска экземпляра Some (возможно, может существовать более одного экземпляра Some, который находится в Num - так какой же выбрать?)

...