Шаблоны объявлений данных Haskell, которые выводят Show - PullRequest
8 голосов
/ 31 декабря 2011

Следующее не компилируется:

import Language.Haskell.TH
makeAlpha n = [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]

Я не могу понять, что вообще означает ошибка:

Can't derive instances where the instance context mentions
type variables that are not data type parameters
  Offending constraint: Show t_d
When deriving the instance for (Show Alpha)
In the Template Haskell quotation
  [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]
In the expression:
  [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]

Можно ли сделать такие деривации?

1 Ответ

7 голосов
/ 31 декабря 2011

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

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

data Alpha = Alpha t deriving (Show, Read)

Это не работает, поскольку производные экземпляры Show и Read должны использовать Show и Read для t, но, поскольку t не является параметром типа Alpha, он не может добавить необходимые ограничения.Конечно, когда выполняется это соединение, t заменяется конкретным типом, поэтому соответствующие экземпляры будут доступны без каких-либо ограничений, так что это один из случаев, когда компилятор слишком осторожен.

Обходной путь - не использовать кавычки, а вместо этого использовать комбинаторы TH, которые не подлежат этим дополнительным проверкам.Это грязно, но работает:

makeAlpha n = sequence [dataD (cxt []) alpha []
                [normalC alpha [strictType notStrict (conT n)]] [''Show, ''Read]]
  where alpha = mkName "Alpha"

были некоторые разговоры о том, чтобы ослабить проверки, сделанные в кавычках , но сейчас вам просто придется иметь дело с этим.

...