Упаковка значения в экзистенциальный тип, зная только класс типа

В дополнение к моей цели по сокращению шаблона, необходимого для использования Haxl с реляционной базой данных, я пытаюсь упаковать результат необработанного запроса SQL через Persistent в экзистенциально количественно выраженный тип. Однако проверка типов не позволит этого:

data SomeRawSql where
  SomeRawSql :: forall b. RawSql b => [b] -> SomeRawSql

packedVal = let res = runDB $ rawSql "SELECT * FROM ..." [toPersistValue (pack "ABC")]
             in fmap SomeRawSql res

Это приводит к ошибке типа в строке с fmap: Ambiguous type variable ‘b0’ arising from a use of ‘SomeRawSql’ prevents the constraint ‘(RawSql b0)’ from being solved.

Тип rawSql из постоянного:

rawSql :: (RawSql a, MonadIO m)
       => Text             -- ^ SQL statement, possibly with placeholders.
       -> [PersistValue]   -- ^ Values to fill the placeholders.
       -> ReaderT SqlBackend m [a]

runDB вспомогательная функция, которая подключается к базе данных и возвращает IO [a], Исходя из определения rawSql, я ожидаю, что ограничение RawSql будет выполнено. Я не понимаю, почему возникает эта ошибка.

1 ответ

rawSql универсально количественно. Это означает, что он не "извлекает RawSql экземпляр из базы данных ", который будет то, что экзистенциальный тип SomeRawSql выражает. Вместо этого он может извлекать значения из базы данных, если они имеют RawSqlэкземпляр. Какой это тип выбирается вызывающим абонентом.

Вы также можете обернуть универсальное количественное определение в тип без параметров:

data SomeRawSql where
  SomeRawSql :: (forall b. RawSql b => [b]) -> SomeRawSql

но я не думаю, что это было бы разумно, это просто пнуло бремя выбора типа в будущем. Параметричность - хорошая вещь, она позволяет вам фактически отслеживать, какие типы и куда идут. Не обходите это без реальной причины!

Совсем другой предмет - если вы хотите получить значение, тип которого вы на самом деле не знаете. Это не покрытоrawSql, вам нужно реализовать это самостоятельно с помощью обертокDynamic,

Другие вопросы по тегам