LINUX.ORG.RU

No instance for (Num t0) arising from the literal `3' The type variable `t0' is ambiguous

 


0

2
class FooAble t where
    foo :: t->Bool
    foo _ = False

instance FooAble Int where
  foo x | x == 3 = True
        | otherwise = False

при попытке выполнить foo 3 появляется ошибка:

*Nat> foo 3

<interactive>:113:1:
    No instance for (FooAble t0) arising from a use of `foo'
    The type variable `t0' is ambiguous
    Note: there is a potential instance available:
      instance FooAble Int -- Defined at Nat.hs:75:10
    In the expression: foo 3
    In an equation for `it': it = foo 3

<interactive>:113:5:
    No instance for (Num t0) arising from the literal `3'
    The type variable `t0' is ambiguous
    Note: there are several potential instances:
      instance Integral a => Num (GHC.Real.Ratio a)
        -- Defined in `GHC.Real'
      instance Num Integer -- Defined in `GHC.Num'
      instance Num Double -- Defined in `GHC.Float'
      ...plus three others
    In the first argument of `foo', namely `3'
    In the expression: foo 3
    In an equation for `it': it = foo 3
*Nat>

как справиться с ошибкой? написание (fromInteger 3) и там и там не помогает

и еще такой вопрос: могу ли я в области сопоставления с образцом писать

foo 3 = ...
, ведь он автоматически раскрывается в
foo (fromInteger 3) = ...
, а fromInteger - это функция, а не конструктор?


Ответ на: комментарий от hateyoufeel

OK, спасибо, идем дальше:

class {-(Num t)=>-}FooAble t where
    foo :: t->Bool
    foo _ = False

instance FooAble Int where
  foo 3 = True
  foo _ = False

instance FooAble Char where
  foo '3' = True
  foo _   = False

instance FooAble String where
  foo "3" = True
  foo _   = False
при загрузке выдает
Nat.hs:83:10:
    Illegal instance declaration for `FooAble String'
      (All instance types must be of the form (T t1 ... tn)
       where T is not a synonym.
       Use TypeSynonymInstances if you want to disable this.)
    In the instance declaration for `FooAble String'
Failed, modules loaded: none.
а
instance FooAble [Char] where
  foo "3" = True
  foo _   = False
выдает
Nat.hs:83:10:
    Illegal instance declaration for `FooAble [Char]'
      (All instance types must be of the form (T a1 ... an)
       where a1 ... an are *distinct type variables*,
       and each type variable appears at most once in the instance head.
       Use FlexibleInstances if you want to disable this.)
    In the instance declaration for `FooAble [Char]'
Failed, modules loaded: none.

FeelUs
() автор топика
Ответ на: комментарий от FeelUs

Транслятор желает увидеть следующие прагмы в начале твоего файла:

{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}

Другой вопрос, насколько верно то, что ты пишешь. Иногда прагмы действительно необходимы.

dave ★★★★★
()
Ответ на: комментарий от FeelUs

Возможно, это тот случай, где лучше задуматься о зависимом инстанцировании:

instance FooAble t => FooAble [t]

Завязка на String не особо нравится транслятору, что вполне понятно. Всякий overloading может случится (??) на списках других типов, если ты начнешь их инстанцировать. String - это по сути синоним:

type String = [Char]
dave ★★★★★
()
Ответ на: комментарий от FeelUs

Попробуй начать осмысливать то, что тебе компилятор пишет, перед тем как бежать на форум плакать.

anonymous
()
Ответ на: комментарий от FeelUs
      (All instance types must be of the form (T a1 ... an)
       where a1 ... an are *distinct type variables*,
       and each type variable appears at most once in the instance head.

Здесь

instance FooAble [Char] where
является эквивалентом
instance FooAble ([] Char) where
GHC ожидает вместо точного типа Char типовую переменную.
instance FooAble ([] a) where

Чтобы позволить более сложные инстансы есть множество расширений. Одно из прямолинейных:

{-# LANGUAGE GADTs #-}
...
instance (a ~ Char) => FooAble [a] where

Чтобы позволить функции работать на любом Num придeтся разрешить неоднозначности в выборе инстансов:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
...
instance (Eq a, Num a) => FooAble a where

Это грозит тем, что расширяя код

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
...
instance (Eq a, Num a) => FooAble a where

instance (SomethingElse a) => FooAble a where

data Something
instance Eq Something
instance Num Something
instance SomethingElse Something
типы Something, которые имеют и '(Eq a, Num a)' и 'SomethingElse a' инстансы будут иметь неоднозначность выбора инстанса.

Некоторые не боятся даже этого и используют OverlappingInstances :) https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/type-class-ex...

sf ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.