Попытка указать значение по умолчанию для одного метода, используя что-то вроде:
instance (Ord v, Fractional w) => Distribution d v w where
probability d v = probabilityOfRange d v v
не будет работать. Экземпляры на Haskell не «накапливаются». Для данной тройки типов d v w
будет применяться не более одного условия instance Distribution d v w
. (Если из-за «перекрывающихся» экземпляров могут применяться несколько предложений , существуют механизмы для выбора «наилучшего» соответствия, но нет прямых механизмов для объединения методов из нескольких предложений экземпляров.)
В общем, если у вас есть метод класса:
class Distribution d v w where
probability :: d v w -> v w
и вы хотите определить метод по умолчанию с более строгой сигнатурой типа (т. Е. С ограничениями для некоторых типов):
probability :: (Ord v) => d v w -> v -> w
probability d v = probabilityOfRange d v v
Есть два подхода.
Первый - использовать расширение DefaultSignatures
. Это позволяет отделить сигнатуру типа для метода от (возможно, более строгой) сигнатуры типа метода default . Синтаксис:
class Fractional w => Distribution d v w where
probability :: d v w -> v -> w
default probability :: (Ord v) => d v w -> v -> w
probability d v = probabilityOfRange d v v
...
Предостережение заключается в том, что если вы определяете экземпляр, который не переопределяет метод по умолчанию, то он должен удовлетворять ограничению Ord v
, иначе он не будет проверять тип.
Если вам нужен больший контроль над использованием метода по умолчанию, тогда обычный подход состоит в том, чтобы разделить определение по умолчанию на отдельную функцию, которая должна быть явно включена в экземпляры, которые хотят его использовать. Итак, у вас будет:
class Fractional w => Distribution d v w where
probability :: d v w -> v -> w
probabilityDefault :: (Distribution d v w, Ord v) => d v w -> v -> w
probabilityDefault d v = probabilityOfRange d v v
и экземпляр, который хочет использовать значение по умолчанию, должен сделать это явно:
instance Distribution Whatever Int w where
probability = probabilityDefault