Деконструкция GADT: где я теряю контекст?

У меня есть этот тип и эти функции:

data Tag a where
    Tag :: (Show a, Eq a, Ord a, Storable a, Binary a) => a -> BL.ByteString -> Tag a

getVal :: Tag a -> a
getVal (Tag v _) = v

isBigger :: Tag a -> Tag a -> Bool
a `isBigger` b = (getVal a) > (getVal b)

Код не проверяет тип:

No instance for (Ord a)
  arising from a use of `>'
In the expression: (getVal a) > (getVal b)
In an equation for `isBigger':
    a isBigger b = (getVal a) > (getVal b)

Но я не могу понять, почему нет. Tag a имеет контекст (Show a, Eq a, Ord a, Storable a, Binary a), а также getVaЯ должен сохранить этот контекст. Я делаю это неправильно или это ограничение расширения GADT?

Это работает:

isBigger :: Tag a -> Tag a -> Bool
(Tag a _) `isBigger` (Tag b _) = a > b

Изменить: я изменил пример на минимальный пример

Редактировать: Хорошо, почему не эта проверка типов?

isBigger :: Tag a -> Tag a -> Bool
isBigger ta tb =
    let (Tag a _) = ta
        (Tag b _) = tb
    in
        a > b

1 ответ

Решение

Ваш тип подписи для getVal не правильно, вы хотели бы тип

 getVal (Storable a, Ord a, ...) => Tag a -> a
 getVal (Tag v _) = v

Причина этого не в том, что вы можете делать такие вещи, как

 doh :: Tag a
 doh = undefined

Теперь, когда a не имеет никаких ограничений на это. Мы можем сделать что-то вроде

 getVal (doh :: Tag (IO Int)) == getVal (doh :: Tag (IO Int))

если getVal были те ограничения.

Единственные нижние экземпляры Tag У вас есть ограничения класса типов, но этого недостаточно для проверки типов с тех пор, как это будет несовместимо с bottom.


Ответить на новый вопрос

Когда вы деконструируете такие типы

 foo tag = let (Tag a _) = tag
               (Tag b _) = tag
           in a > b

GHC не объединяет их должным образом. Я подозреваю, что это потому, что проверщик типов уже определился с типом a к тому времени, когда будет достигнуто совпадение с образцом, но при сопоставлении с верхним уровнем оно будет правильно объединено.

 foo (Tag a _) (Tag b _) = a > b
Другие вопросы по тегам