Рассмотрим следующий код:
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.HList.GhcSyntax((.!.),(.=.),(.*.))
import Data.HList.Record(emptyRecord)
import Data.HList.TypeCastGeneric1
import Data.HList.TypeEqGeneric1
import Data.HList.Label5
data Hello1 = Hello1
data Hello2 = Hello2
record = (Hello1 .=. "Hello1") .*. (Hello2 .=. "Hello2") .*. emptyRecord
f1 = $([| (\r1 -> (r1 .!. Hello1)) |])
main = print $ f1 record
Это компилируется нормально и выводит «Hello1», как и ожидалось.
Однако добавление следующей строки (GHC 7.4.1) приводит к ошибке компиляции:
f2 = $([| (\r2 -> (r2 .!. Hello2)) |])
Указана ошибка:
error.hs:16:1:
Could not deduce (Data.HList.Record.HasField Hello2 r0 v0)
arising from the ambiguity check for `main'
from the context (Data.HList.Record.HasField Hello2 r v)
bound by the inferred type for `main':
Data.HList.Record.HasField Hello2 r v => IO ()
at error.hs:(16,1)-(20,38)
Possible fix:
add an instance declaration for
(Data.HList.Record.HasField Hello2 r0 v0)
When checking that `main'
has the inferred type `forall r v.
Data.HList.Record.HasField Hello2 r v =>
IO ()'
Probable cause: the inferred type is ambiguous
error.hs:16:1:
Could not deduce (Data.HList.Record.HasField Hello2 r0 v0)
arising from the ambiguity check for `f1'
from the context (Data.HList.Record.HasField Hello2 r v)
bound by the inferred type for `f1':
Data.HList.Record.HasField Hello2 r v =>
Data.HList.Record.Record
(Data.HList.HListPrelude.HCons
(Data.HList.Record.LVPair Hello1 [Char])
(Data.HList.HListPrelude.HCons
(Data.HList.Record.LVPair Hello2 [Char])
Data.HList.HListPrelude.HNil))
-> [Char]
at error.hs:(16,1)-(20,38)
Possible fix:
add an instance declaration for
(Data.HList.Record.HasField Hello2 r0 v0)
When checking that `f1'
has the inferred type `forall r v.
Data.HList.Record.HasField Hello2 r v =>
Data.HList.Record.Record
(Data.HList.HListPrelude.HCons
(Data.HList.Record.LVPair Hello1 [Char])
(Data.HList.HListPrelude.HCons
(Data.HList.Record.LVPair Hello2 [Char])
Data.HList.HListPrelude.HNil))
-> [Char]'
Probable cause: the inferred type is ambiguous
Почему добавление строки f2
приводит к ошибке компиляции?
Примечание. Части Template Haskell здесь могут выглядеть глупо, но они представляют собой упрощение более сложного Template Haskell, который работает с кортежами. Я опубликовал самый простой пример, который я мог построить, который все еще демонстрировал ошибку. Я понимаю, что в данном случае удаление Template Haskell решает проблему, но в моем реальном коде это невозможно.
Изменить:
Кроме того, следующее не удается скомпилировать. Почему это так:
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.HList.GhcSyntax((.!.),(.=.),(.*.))
import Data.HList.Record(emptyRecord)
import Data.HList.TypeCastGeneric1
import Data.HList.TypeEqGeneric1
import Data.HList.Label5
data Hello1 = Hello1
data Hello2 = Hello2
data Hello3 = Hello3
record1 = (Hello1 .=. "Hello1") .*. (Hello2 .=. "Hello2") .*. emptyRecord
record2 = (Hello1 .=. "Hello1") .*. (Hello2 .=. "Hello2") .*. (Hello3 .=. "Hello3") .*. emptyRecord
f1 = $([| (\r1 -> (r1 .!. Hello1)) |])
main = print $ (f1 record1, f1 record2)
f2
вы используете его где-нибудь? Если нет, сработает ли это, если вы дадитеf2
явную аннотацию типа? - person Daniel Wagner   schedule 27.08.2012f2
, кажется, помогает. Однако я обнаружил другие проблемы. См. раздел stackoverflow.com/questions/12144250/ пример проблемы, не связанной с HList. - person Clinton   schedule 27.08.2012