#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 .