У меня есть этот тип и эти функции:Деконструкция 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)
Код не typecheck:
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
Edit: Я изменил пример минимального примера
Edit: Хорошо, почему не это typecheck?
isBigger :: Tag a -> Tag a -> Bool
isBigger ta tb =
let (Tag a _) = ta
(Tag b _) = tb
in
a > b
Еще раз спасибо joze. Я не могу сказать, что я понимаю, почему это проблема, потому что она не является нижней строкой во всем мире? Но на данный момент достаточно знать, что просто невозможно, не может быть сделано, по какой-то причине теории эзотерической категории. – masonk
Это просто, что можно сделать экземпляры 'Tag', которые имеют' a', который не ограничен с использованием 'undefined' , Подумайте о 'undefined' в качестве секретного конструктора для любого типа, даже тех, которые не могут существовать без' undefined'. – jozefg
Хорошо, еще одна сложность. Почему эта третья версия 'isBigger' typecheck? Это использование соответствия шаблону! Здесь нет ничего скрытого. – masonk