Тип вашей функции
addTypes :: Expr -> TypedExpr t
неправильный, потому что это будет означать, что вы получите TypedExpr t
для любого t
, который вам нравится .Напротив, на самом деле вам нужен один конкретный t
, который определяется аргументом типа Expr
.
. Это рассуждение уже показывает, что вы выходите за пределы возможностейСистема типов Хиндли-Милнера.В конце концов, возвращаемый тип из addTypes
должен зависеть от значения аргумента, но в простом Haskell 2010 типы могут не зависеть от значений.Следовательно, вам нужно расширение системы типов, которое приблизит вас к зависимым типам .В Haskell это могут сделать обобщенные алгебраические типы данных (GADT).
Для первого знакомства с GADT см. Также мое видео о GADT .
Однако, после ознакомления с GADT, у вас все еще остается проблема разбора нетипизированного выражения в типизированное, т.е. написать функцию
addTypes :: Expr -> (exists t. TypedExpr t)
Конечно, вы должны выполнить некоторую проверку типа самостоятельноНо даже тогда непросто убедить компилятор Haskell, что ваши проверки типов (которые происходят на уровне значений) могут быть подняты до уровня типов.К счастью, другие люди уже подумали об этом, например, посмотрите следующее сообщение в списке рассылки haskell-cafe:
Эдвард Кметт .
Re: Ручной тип-Проверка предоставления экземпляров Read для GADT.(было Re: [Haskell-cafe] Читать экземпляр для GATD)
http://article.gmane.org/gmane.comp.lang.haskell.cafe/76466
(Кто-нибудь знает о официально опубликованной / хорошо написанной ссылке?)