Как использовать fromInteger без неявной прелюдии в Haskell? - PullRequest
8 голосов
/ 19 октября 2010

Следующая программа выдает ошибку в 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<br> Possible fix: add an instance declaration for (Monoid Integer)<br> In the pattern: 1<br> In the definition of fromInteger ': fromInteger 1 = один

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

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

1 Ответ

7 голосов
/ 19 октября 2010

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

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

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

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

fromInteger x | x == integerOne = one
...