Как использовать fromInteger без неявной прелюдии в Haskell?

Следующая программа выдает ошибку в ghci:

{-# LANGUAGE NoImplicitPrelude #-}

import Prelude (Integer, Bool)
import qualified Prelude

class Discrete a where
    (==) :: a -> a -> Bool

instance Discrete Integer where
    (==) = (Prelude.==)

class Monoid a where
    one :: a
    (*) :: a -> a -> a

    fromInteger :: Integer -> a
    fromInteger 1 = one

А именно:

fromInteger.hs: 17: 16:
Нет экземпляра для (Monoid Integer)
возникающего из литерала 1' at fromInteger.hs:17:16
Possible fix: add an instance declaration for (Monoid Integer)
In the pattern: 1
In the definition of
fromInteger ': fromInteger 1 = one

Как я могу это исправить, чтобы 1 можно было преобразовать в значение one для моноидов? Все остальные целые числа могут (или должны) давать Prelude.undefined при применении к (Monoid a) => fromInteger.

Имейте в виду, что я - полная противоположность эксперту по Haskell, поэтому, пожалуйста, простите меня, если ответ очевиден.


person Marc    schedule 19.10.2010    source источник


Ответы (1)


Проблема в том, что (с NoImplitPrelude) вы можете использовать целочисленные литералы только для типов, для которых есть функция fromInteger в области видимости.

Таким образом, в вашем коде вы можете использовать только целочисленные литералы для представления экземпляров Monoid, а поскольку в вашем коде Integer не является экземпляром Monoid, вы не можете использовать литерал 1 для представления целого числа 1.

Чтобы исправить это, вы можете создать другой модуль, который импортирует прелюдию и определяет integerOne :: Integer = 1.

Затем вы можете определить свою fromInteger функцию как:

fromInteger x | x == integerOne = one
person sepp2k    schedule 19.10.2010