2016-05-23 48 views
6

在GHC 8:如何消除選擇器功能的歧義?

{-# LANGUAGE DuplicateRecordFields #-} 

data Dog = Dog { name::String } 
data Human = Human { name::String } 

dog = Dog "Spike" 


main = putStrLn $ name dog 

此代碼不能編譯:

Ambiguous occurrence `name' 
It could refer to either the field `name', defined at A.hs:4:22 
         or the field `name', defined at A.hs:3:18 

如何正確取回我的狗的名字嗎?

+5

啊,模棱兩可的記錄字段......不知道該kludgy修復擴展鏈是無限的嗎?如果是,我們需要一個DisambiguateRecordFieldsDisambiguationExte nsion'的擴展? - ...一定要看看[尼基塔沃爾科夫的'唱片庫](https://nikita-volkov.github.io/record/),這應該使這些擴展完全沒有必要。 - (FTR:我不認爲這些擴展名的作者做得不好,事實上我過去使用過'RecordWildCards',發現它工作得很好。但是,我敢說它總體上不是正確的方法) – leftaroundabout

回答

6

這應該工作:

main = putStrLn $ name (dog :: Dog) 

看到DuplicateRecordFields的詳細信息:

領域的裸用途僅指選擇器功能,並且只工作,如果這是毫不含糊的。

然而,我們並不推斷出參數的類型來確定數據類型,或有推遲的選擇約束求解器的任何方式。

的例子有很多像你這樣的:

bad (p :: Person) = personId p

時,有一個在範圍personId領域的又一紀錄這是不行的 - 即使它似乎是顯而易見:(

+3

等等,但是現在不是GHC那'狗'有類型'狗'? – ZhekaKozlov

+0

看到引文...你是對的,但這不是它是如何工作/推斷 - 如果你使用通常沒有問題的簽名 – Carsten

+1

哦,我相信這個語言擴展將是我最喜歡的! – epsilonhalbe