Ошибки множественных объявлений при перегрузке функции класса типов

#haskell #overloading #typeclass

#haskell #перегрузка #класс типов

Вопрос:

Следующий код представляет собой пример кода для перегрузки функций частично упорядоченного класса типов (POrd) со слайда лекции.

При попытке запустить этот код я получаю следующие ошибки множественных объявлений для функции ‘pcompare’ и для операторов.

 > class Eq a => POrd a where
>    pcompare :: a -> a -> Maybe Ordering
>    (~<), (~>), (~<=), (~>=) :: a -> a -> Bool
>
>       -- Minimal complete definition:
>       --      (~<)amp; (~>) | pcompare
> pcompare x y | x == y       = Just EQ
>              | x ~< y       = Just LT
>              | x ~> y       = Just GT
>              | otherwise    = Nothing
>
> x ~<= y = pcompare x y ==  Just LT || x == y
> x ~<  y = pcompare x y ==  Just LT
> x ~>= y = pcompare x y ==  Just GT || x == y
> x ~>  y = pcompare x y ==  Just GT


 

Я получаю следующие сообщения об ошибках:

 lecture9.lhs:5:1: error:
    Multiple declarations of `pcompare'
    Declared at: lecture9.hs:2:4
                 lecture9.hs:5:1
  |
5 | pcompare x y | x == y       = Just EQ
  | ^^^^^^^^

lecture9.lhs:10:3: error:
    Multiple declarations of `~<='
    Declared at: lecture9.lhs:3:4
                 lecture9.lhs:10:3
   |
10 | x ~<= y = pcompare x y ==  Just LT || x == y
   |   ^^^

lecture9.lhs:11:3: error:
    Multiple declarations of `~<'
    Declared at: lecture9.lhs:3:4
                 lecture9.lhs:11:3
   |
11 | x ~<  y = pcompare x y ==  Just LT
   |   ^^

lecture9.lhs:12:3: error:
    Multiple declarations of `~>='
    Declared at: lecture9.lhs:3:4
                 lecture9.lhs:12:3
   |
12 | x ~>= y = pcompare x y ==  Just GT || x == y
   |   ^^^

lecture9.lhs:13:3: error:
    Multiple declarations of `~>'
    Declared at: lecture9.lhs:3:4
                 lecture9.lhs:13:3
   |
13 | x ~>  y = pcompare x y ==  Just GT
   |   ^^
 

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

Комментарии:

1. Трудно быть уверенным, потому что в вашем коде есть посторонние > символы в начале каждой строки, но я думаю, что это связано с отступом. Весь этот код является частью определения класса типов, поэтому он должен иметь тот же уровень отступа, что class и само объявление.

2. Это абсолютно проблема с отступом. После pcompare объявления в определении класса оно может быть «переопределено» только в instance объявлении. Не pcompare делая отступов, вы пытаетесь определить ее как обычную функцию.

3. @chepner Или в class объявлении, в качестве реализации по умолчанию! (Я думаю, это то, что пытается сделать OP.)

4. @bradrn Я предположил, что это то, что имел в виду OP. Я имел в виду, что объявление / определение должно было произойти в объявлении класса, но это не ясно из моего комментария.

5. Если у вас возникли проблемы с отступом, обратите внимание, что это синтаксический сахар для фигурных скобок вокруг блоков (например, where amp; let (… in ), do , case of ) и точек с запятой между элементами (соответственно. объявления и определения, монадические операторы, case ветви). Если вы напишете их явно, проблемы могут стать очевидными. Как уже объяснялось в ответах, ваш отступ означал class … POrd a where { pcompare :: …; (~<), (~>), (~<=), (~>=) :: …; }; pcompare x y …; x ~<= y …; … , что реализации по умолчанию находились вне блока, но должны быть внутри (с отступом).

Ответ №1:

Как отмечают комментаторы вашего вопроса, проблема заключается в отступах. Как бы то ни было, > символы подходят, учитывая, что вы пытаетесь скомпилировать грамотный файл Haskell (.lhs), а не обычный файл Haskell. (Тем не менее, в обычном файле Haskell (.hs) они могут вызвать ошибки синтаксического анализа.)

В Haskell объявления «верхнего уровня» вообще не имеют отступов. Например, определение POrd класса не имеет отступа. С другой стороны, объявления не верхнего уровня должны иметь отступ. Объявления типов pcompare и других операторов являются частью POrd класса и, как таковые, имеют отступ.

Определения pcompare и другие операторы также должны иметь отступы, но технически они могут находиться в двух разных местах. Они могут быть определены для конкретных экземпляров POrd , или они могут быть определены как значения по умолчанию для POrd класса. Основываясь на самих определениях, кажется, что они предназначены по умолчанию.

Короче говоря, если вы сделаете отступ в определениях pcompare и других операторах, у вас все должно получиться. (Имейте в виду, что > все еще должно быть в начале строки, поэтому добавьте дополнительные пробелы сразу после > , как в > pcompare x y | x == y ... .)

Комментарии:

1. Небольшое изменение этого ответа: возможно, вам следует уточнить, что > это происходит в начале только в грамотном файле Haskell .