2013-08-28 26 views
3

我有一個數據結構,可以理解爲類似於Data.Map,因爲它將一種類型的鍵映射到另一種類型的值。我想寫這種類型的Control.Lens.At的實例,但我似乎無法滿足所有要求。如何編寫Control.Lens.AT實例

鑑於Struct k vlookupinsertupdatedelete,我必須做什麼,使instance At (Struct k v)工作?

回答

6

at方法應該返回一個索引的鏡頭對於給定的索引獲取輸入您的結構和行爲方式是這樣的:

  • 在獲取時,如果該鍵不存在,返回Nothing,在否則返回值結構中的關鍵。
  • 進行設置時,如果新值爲Nothing,則從結構中除去該鍵,否則將其設置爲(或者在尚未存在的情況下將其創建)爲Just中的值。
  • 該指數只是給予at的關鍵。

這導致下面的代碼爲您的要求:

instance At (Struct k v) where 
    at key = ilens getter setter 
    where getter = (key, lookup key) 
      setter s Nothing = delete key s 
      setter s (Just newValue) = insert key newValue s 

我用 lens構建一個鏡頭 ilens從一個getter和一個setter構建索引的鏡頭。我還以爲你的職責有以下幾種類型:

lookup :: k -> Struct k v -> Maybe v 
delete :: k -> Struct k v -> Struct k v 
insert :: k -> v -> Struct k v -> Struct k v 
-- Insert should override the key when it's already there 

你仍然需要定義IxValueIndex型家庭情況:

type instance IxValue (Struct k v) = v -- A (Struct k v) contains values of type v 
type instance Index (Struct k v) = k -- A (Struct k v) has keys of type k. 

編輯:其實,在必須返回一個索引鏡頭,而不僅僅是一個鏡頭。我也混淆了二元論的順序。

+0

請注意'透鏡'(或'ilens')通常不是製作鏡片的推薦方法。直接寫入通常會更好。 – shachaf

+0

@shachaf這是爲什麼? – bennofs

+0

它通常更冗長和效率更低(不共享)。 – shachaf