簡體   English   中英

在Haskell中的case語句中使用默認值

[英]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,其他案例甚至都不存在

這有利有弊。 窮舉意味着您和編譯器可以保證您的函數正在處理它們將被給予的所有可能輸入。 缺點是在編譯時固定了一組案例。

這里最簡單的選擇是兩部分:

  1. 使用“開放”類型 - 您可以在運行時創建任意多個不同的實例 - 來表示國家和大寫字母。 弦樂在這里很好; 您可以在運行時構建無限數量的不同字符串。 但您也可以使用帶有字符串成員的記錄類型。
  2. 使用鍵/值分配數據結構來表示國家和首都之間的關聯。

所以你可以像這樣代表國家和城市:

-- 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM