2
考慮下面的代碼:模板哈斯克爾編譯錯誤
{-# 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
線導致編譯錯誤?
注意:模板Haskell部分在這裏可能看起來很愚蠢,但它們是更復雜的模板Haskell的簡化,它可以在元組上工作。我發佈了我可以構建的最簡單的示例,但仍然顯示錯誤。我意識到在這種情況下刪除模板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'一個明確的類型註解,它是否工作? –
@DanielWagner:使用'f2'似乎有所幫助。但是,我發現了其他問題。請參閱http://stackoverflow.com/questions/12144250/template-haskell-compile-error-when-calling-with-different-parameters關於不涉及HList的問題的示例。 – Clinton
@DanielWagner:再想一想,或許這個問題是一個紅鯡魚,儘管它可能是相關的。我找到了一個解決方法,並將其作爲我自己問題的答案,這不是理想的,但對我的問題可行的解決方案。 – Clinton