Я читал о создании наших собственных типов и классов типов из Learn You a Haskell for Great Good. Я не совсем понимаю поведение компилятора Haskell, когда я добавляю ограничение типа к своим объявлениям data
.
Например, у меня есть
{-# LANGUAGE DatatypeContexts #-}
data (Ord a) => OrderedValue a = OrderedValue a
getOrderedValue :: OrderedValue a -> a
getOrderedValue (OrderedValue a) = a
Как видно выше, у меня есть ограничение типа для моего объявления данных, согласно которому любое значение, содержащееся внутри OrderedValue
, должно иметь экземпляр Ord
.
Я попытался скомпилировать этот код, и компилятор выплюнул
• No instance for (Ord a) arising from a use of ‘OrderedValue’
Possible fix:
add (Ord a) to the context of
the type signature for:
getOrderedValue :: forall a. OrderedValue a -> a
• In the pattern: OrderedValue a
In an equation for ‘getOrderedValue’:
getOrderedValue (OrderedValue a) = a
Изменение определения getOrderedValue
на
getOrderedValue :: (Ord a) => OrderedValue a -> a
getOrderedValue (OrderedValue a) = a
ожидаемо исправил проблему.
У меня вопрос - почему компилятор здесь жалуется? Я предположил, что компилятор должен иметь возможность сделать вывод, что шаблон a
соответствует в
getOrderedValue (OrderedValue a) = a
имеет экземпляр Ord
, потому что конструктор значения OrderedValue
предназначен для создания экземпляров типа OrderedValue
с параметром типа a
, имеющим экземпляр Ord
.
Уф, это был полный рот.
Спасибо.
ИЗМЕНИТЬ - я просмотрел альтернативные ответы, предложенные @melpomene, спасибо за это. Однако я ищу ответ, который описывает почему разработчики языка Haskell решили реализовать его именно таким образом.
sort :: IO Double -> Char
, то это обязательно вызовет ошибку времени компиляции. Дело в том, что вы можете спросить компилятор, какова (наиболее общая) правильная подпись, вместо того, чтобы писать ее самостоятельно - хотя чаще всего лучше начать с подписи и позволить компилятору помочь вам с реализацией < / i> вместо этого. И иногда подписи действительно необходимы, особенно когда задействованы типы Rank-2. - person leftaroundabout   schedule 17.10.2018data
. Они действительно ничего не добавляют к вашему типу и вызывают только головную боль. Есть альтернативы получше. - person Bakuriu   schedule 18.10.2018