簡體   English   中英

帶折疊的地圖查找功能

[英]Map lookup function with fold

我想使用折疊創建“地圖查找”功能。

這是我的“地圖”(只是一個元組列表):

phoneBook:: [([Char], [Char])]
phoneBook = [("bob", "00-21-55")
            ,("jack", "55-51-55")
            ,("joe", "10-61-25")
            ,("susy", "06-21-55")
            ,("clara", "50-31-95")
            ]

這是我想編寫的函數:

lookUp :: (Eq k) => k -> [(k,v)] -> v
lookUp k = foldl1 (\acc (x,y) -> if k == y then y else acc)

但是,這不能編譯,它會產生“無法構造無限類型”錯誤。

您能向我解釋為什么這是錯誤的,以及如何使它起作用嗎?

請注意,我知道Data.Map及其導出的地圖函數,我想這樣做只是為了了解折疊的工作方式。

首先是一個工作版本-我會在幾分鍾后再解釋一下:

lookUp :: (Eq k) => k -> [(k,v)] -> Maybe v
lookUp k = foldl (\ acc (k',v) -> if k == k' then Just v else acc) Nothing            

您遇到的問題是:

  • 對於foldl1您的類型為foldl1 :: (a -> a -> a) -> [a] -> a因此您需要元素和結果使用相同的類型-但在這里您希望將值作為結果但將其折疊鍵/值對的元組。
  • 這就是為什么我改用更通用的foldl (請注意,我對這是否是正確的選擇不感興趣-請參見foldl' foldl vs foldr
  • 這個函數永遠不能是總的(如果鍵不在字典/鍵值對列表中),所以我選擇在結果類型中反映出來,現在Maybe v當然,這使得查找起來非常容易初始值: Nothing

如果您不喜歡Maybe部分,也可以像下面這樣使用error

lookUp :: (Eq k) => k -> [(k,v)] -> v
lookUp k = foldl (\ acc (k',v) -> if k == k' then v else acc) (error "key not found")

備注:

這不是最有效的實現,因為無論您是否找到密鑰,您都將瀏覽所有列表-隨時嘗試提出可以

提示 :Haskell很懶惰-也許您可以通過過濾掉正確的鍵/值對,以確保安全,然后映射到值部分來找到一些東西;))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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