[英]Why is the default catch-all not mandatory in a Haskell case statement?
[英]Using a default in a case statement in Haskell
我正在嘗試創建一個名為place的新數據聲明。
它看起來像這樣:
data place = United States | France | England | Germany | Mexico | Canada
我希望然后使用一個名為cap的函數來取代它的資本,如下所示:
cap :: place -> String
cap a = case a of
Spain -> "Madrid"
France -> "Paris"
England -> "London"
Germany -> "Berlin"
Mexico -> "Mexico City"
Canada -> "Ottawa"
_ -> undefined
但是,最后一種情況,我試圖捕獲數據聲明中可能不存在的所有其他條目不起作用。 如果我在GHCI進入capital Wales
,我不會得到一個不明確的回應。 相反,我得到一個不在范圍內的錯誤。 有人可以幫助我解決我的困惑,也許可以提供一種試圖捕捉其他案件的合法方式嗎?
問題不在於你如何處理丟失的案件 - 你如何處理它是好的。 問題是Wales
構造函數根本不存在。 因此,就像當您嘗試使用尚未定義的變量或函數時,您會收到編譯錯誤。 您的cap
函數甚至不會被調用,因此您無法對其進行任何更改會影響此行為。 使用不存在的構造函數編譯代碼是無法做到的。
當您進入capital Wales
,范圍內沒有Wales
。 您無法構造不存在的值。 如果您已涵蓋所有可能的案例,那么您不需要默認案例。
為了重復sepp2k和singpolyma的答案,這里的重點是Haskell的聯合類型是詳盡無遺的 。 當你定義一個聯合類型具有n個的情況下,你是在告訴哈斯克爾那些n個個案是存在你的類型的唯一案例。 正如singpolyma指出的那樣,你告訴Haskell,其他案例甚至都不存在 。
這有利有弊。 窮舉意味着您和編譯器可以保證您的函數正在處理它們將被給予的所有可能輸入。 缺點是在編譯時固定了一組案例。
這里最簡單的選擇是兩部分:
所以你可以像這樣代表國家和城市:
-- Since there are infinitely many different strings you could construct at runtime,
-- there are also infinitely many different Cities and Nations...
data City = City String deriving (Eq, Ord, Show)
data Nation = Nation String deriving (Eq, Ord, Show
最簡單的鍵/值映射類型是[(k, v)]
,通常稱為關聯列表 。 它當然具有O(n)查找時間。 更好的方法是使用Haskell平台附帶的Data.Map
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.