Я пишу библиотеку для работы с бесконечными последовательностями, используя ленивую оценку. Для краткости я использую обобщенные алгебраические типы данных (GADT), чтобы установить ограничение Ord
для индекса каждого термина в последовательности. Отсюда следующие проверки типов:
{-# LANGUAGE GADTs #-}
data Term ix cff where
Term :: (Ord ix) => ix -> cff -> Term ix cff
data Sequence ix cff where
Seq :: [Term ix cff] -> Sequence ix cff
f (Seq (Term i x:_)) (Seq (Term j y:_)) = i < j
{-
add :: Sequence ix cff -> Sequence ix cff -> Sequence ix cff
add (Seq tms1) (Seq tms2) = Seq (addAlong (<) tms1 tms2)
where addAlong :: (ix -> ix -> Bool) ->
[Term ix cff] -> [Term ix cff] -> [Term ix cff]
addAlong ord (Term i x : tms1) (Term j y : tms2) = []
-}
Как и ожидалось, GHCi сообщает мне, что f :: Sequence t t1 -> Sequence t t2 -> Bool
. Для сравнения i < j
требуется экземпляр Ord
, но об этом заботится ограничение (Ord ix)
в определении Term
.
Однако, когда нижний блок раскомментирован, функция add
не проходит проверку типов с ошибкой No instance for (Ord ix) arising from the use of ``<''
. Разве он не должен вычислить (Ord ix)
из Term ix cff
, которое появляется в определении Sequence
?