為GHC
中的術(shù)語分配文字出于好奇,為什么以下程序1=0quot;=quot;由GHC有效并可編譯?這僅僅是一個bug還是一個特性?謝謝!
解答動態(tài)
這是允許的,因為它是語言規(guī)則的自然結(jié)果,并且沒有問題到足以在語言規(guī)范中做一個特例來阻止它。
自然結(jié)果有兩種標準的定義:函數(shù)定義和數(shù)據(jù)定義。在函數(shù)定義中,可以將模式作為參數(shù)寫入等號左側(cè)的函數(shù)。在數(shù)據(jù)定義中,您可以在等號左側(cè)單獨編寫一個模式,以與等號右側(cè)的數(shù)據(jù)相匹配。所以,這些都是允許:
x=3倍@y=3[x,y,z]=[3,4,5][x,216;,z]=[3,4,5][x,4,z]=[3,4,5]x:216;=quot;x:quot;=quot; 數(shù)字文字和字符串文字是模式。(以前的德斯加變成了一個叫(=)的守衛(wèi))所以這些是允許的,太:
3=3倍@3=3[3,4,5]=[3,4,5]quot;=quot;——是的,這些too3=4quot;=quot; 與語言的所有其他部分沒有問題,數(shù)據(jù)定義是惰性的:它們所表示的模式匹配計算直到需要時才執(zhí)行(通過檢查匹配所綁定的一個變量)。由于quot;=quot;和1=0不綁定任何變量,因此它們所表示的模式匹配計算(將引發(fā)異常)永遠不會執(zhí)行。所以不允許他們也不是特別重要。
…除非是等待。。。我們說這是有效的圖案:
x@3=3這相似的一個分開并結(jié)合了一個變量:
x@3=4 為什么允許這樣做?這很難回答!我認為應(yīng)該考慮一些語言規(guī)則來防止這種情況的發(fā)生。一般來說,一個合理而完整的規(guī)則當然是不可判定的,因為方程的右邊可以進行任意計算。但你也可以做出其他選擇,比如例如:不要允許在數(shù)據(jù)定義中使用可反駁的模式。如果一個模式不能匹配,它是可以反駁的。例如,x是無可辯駁的,x@y公司是無可辯駁的,u是無可辯駁的,但是x:y是可辯駁的,True是可辯駁的,()是可辯駁的(因為當RHS在底部時它會發(fā)散)。這是迄今為止最簡單的,并且排除了x@3個=4和quot;=quot;都是。不幸的是,它還排除了像[x,y,z]=[3,4,5]這樣非常有用的東西。實現(xiàn)一個終止檢查器,并要求可反駁模式的rh終止。如果你有一個分析,可以決定一些計算終止——例如,通過發(fā)現(xiàn)其中所有的遞歸都是結(jié)構(gòu)化的或者其他的,有一個完整的終止檢查算法的家庭手工業(yè)——那么你可以讓編譯器檢查它。如果它確實終止了,編譯器實際上可以在編譯期間運行計算,并再次檢查給定的模式是否與值匹配。這樣做的缺點是終止檢查算法非常復(fù)雜,因此這給編譯器編寫者帶來了很大的負擔(dān),而且有些算法很難被人類預(yù)測,這使得針對它的編程對于整個系統(tǒng)來說是令人沮喪的用戶需求程序員證明匹配不會失敗。你可以引入一種機制,讓程序員為他們的程序編寫證明,并要求他們證明匹配不會失敗。這朝著依賴類型的方向發(fā)展;這樣做的兩個主要代價通常是程序效率的降低,用這樣的語言編寫程序需要付出更多的努力。 語言設(shè)計人員做出了許多選擇(不僅僅是在模式匹配語義方面),這些選擇有助于使程序員和編譯器編寫者的生活更輕松一些,但也允許一些錯誤更多從不完成或拋出異常的程序。這就是這樣一個點——在數(shù)據(jù)定義中允許使用可反駁的模式,即使這會導(dǎo)致崩潰,因為該策略的實現(xiàn)是有用的、簡單的和可預(yù)測的。
因為這些文本是模式,所以您使用的是模式綁定。
let在Haskell中綁定是懶惰的,所以沒有實際的模式匹配被執(zhí)行。
但是如果我們強制匹配,它確實失。
gt;alt;interactive>;:87:1-7:模式的無可辯駁模式失敗x@1 原因1實際上不是0.
,所以這不是一個bug,也不是GHC實現(xiàn)的特性,而是Haskell語言本身的特性- End
免責(zé)聲明:
本頁內(nèi)容僅代表作者本人意見,若因此產(chǎn)生任何糾紛由作者本人負責(zé),概與琴島網(wǎng)公司無關(guān)。本頁內(nèi)容僅供參考,請您根據(jù)自身實際情況謹慎操作。尤其涉及您或第三方利益等事項,請咨詢專業(yè)人士處理。