Первая попытка
Трудно сделать этот вопрос содержательным, но чтобы привести минимальный пример, предположим, что у меня есть этот тип:
{-# LANGUAGE GADTs #-}
data Val where
Val :: Eq a => a -> Val
Этот тип позволяет мне с радостью построить следующий гетерогенныйсписок:
l = [Val 5, Val True, Val "Hello!"]
Но, увы, когда я записываю Eq
экземпляр, все идет не так:
instance Eq Val where
(Val x) == (Val y) = x == y -- type error
Ах, значит, мы Could not deduce (a1 ~ a)
.Совершенно верно;в определении нет ничего, что говорит, что x
и y
должны быть одного типа.Фактически, весь смысл состоял в том, чтобы допустить возможность того, что они различаются.
Вторая попытка
Давайте добавим Data.Typeable
в микс и попробуем сравнить два, только если они одного типа:
data Val2 where
Val2 :: (Eq a, Typeable a) => a -> Val2
instance Eq Val2 where
(Val2 x) == (Val2 y) = fromMaybe False $ (==) x <$> cast y
Это довольноотлично.Если x
и y
имеют одинаковый тип, он использует базовый экземпляр Eq
.Если они отличаются, он просто возвращает False
.Однако эта проверка откладывается до времени выполнения, что позволяет nonsense = Val2 True == Val2 "Hello"
проверять тип без жалоб.
Вопрос
Я понимаю, что заигрываю с зависимыми типами здесь, но возможно ли это для типа Haskellсистема статически отклоняет что-то вроде выше nonsense
, в то же время позволяя что-то вроде sensible = Val2 True == Val2 False
вернуть False
во время выполнения?
Чем больше я работаю с этой проблемой, тем больше, кажется, мне нужно принятьнекоторые методы HList для реализации операций, которые мне нужны как функции уровня типа.Тем не менее, я относительно новичок в использовании существующих и GADT, и мне любопытно узнать, есть ли решение, которое можно найти именно с ними.Поэтому, если ответ «нет», я был бы очень признателен за обсуждение того, где именно проблема достигает предела этих функций, а также за толчок к подходящим методам, HList или другим.