Я наткнулся на следующую небольшую проблему. Я использую синтаксис записи Haskell, вместе с GADTs:Использование синтаксиса обновления записи с ограниченными записями GADT
{-# LANGUAGE GADTs #-}
data Test a where
Test :: {someString :: String, someData :: a} -> Test a
Теперь я хочу, чтобы создать новое значение Test
с другим типом для someData
, но такое же значение для someString
(чтобы оправдать использование синтаксиса изменения записи):
test :: Test a -> Test Bool
test t = t {someData = True}
Пусть я добавить еще одно поле для Test
конструктора:
data Test a where
Test :: {someString :: String, someData :: a, someMoreData :: a} -> Test a
Тогда Я должен изменить оба поля, чтобы сохранить типа правильно мой код:
test :: Test a -> Test Bool
test t = t {someData = True, someMoreData = False}
До сих пор я не нуждался в GADT, но теперь я хочу, чтобы добавить тип класса ограничение на тип данных, например, Eq
:
data Test a where
Test :: Eq a => {someString :: String, someData :: a} -> Test a
при попытке «обновить» someData
поле, как и в первом примере, я вдруг получаю ошибку компиляции:
Couldn't match type ‘a’ with ‘Bool’
‘a’ is a rigid type variable bound by
the type signature for test :: Test a -> Test Bool at Test.hs:18:9
Expected type: Test Bool
Actual type: Test a
Relevant bindings include
t :: Test a (bound at Test.hs:19:6)
test :: Test a -> Test Bool (bound at Test.hs:19:1)
In the expression: t
In the expression: t {someData = True}
Я подозреваю, что это то же самое «р roblem ", как в случае с двумя полями типа a
, но немного более неявным. Я думаю, словарь для класса типа Eq
рассматривается как аргумент конструктора, как если бы у меня было поле {eqDict :: Eq a}
. Если я прав, то мне также пришлось «обновить» поле «словарь» каким-то образом, хотя я не знаю, как это сделать. Вопрос в том, есть ли способ использовать синтаксис обновления записи, когда классы типов задействованы как это?
Жаль, я полагаю, что я должен придерживаться своего обходного пути. Спасибо за Ваш быстрый ответ. –