Эта проблема возникает из-за того, что кавычки 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"
были некоторые разговоры о том, чтобы ослабить проверки, сделанные в кавычках , но сейчас вам просто придется иметь дело с этим.