3
我有一個數據結構,可以理解爲類似於Data.Map
,因爲它將一種類型的鍵映射到另一種類型的值。我想寫這種類型的Control.Lens.At
的實例,但我似乎無法滿足所有要求。如何編寫Control.Lens.AT實例
鑑於Struct k v
與lookup
,insert
,update
和delete
,我必須做什麼,使instance At (Struct k v)
工作?
我有一個數據結構,可以理解爲類似於Data.Map
,因爲它將一種類型的鍵映射到另一種類型的值。我想寫這種類型的Control.Lens.At
的實例,但我似乎無法滿足所有要求。如何編寫Control.Lens.AT實例
鑑於Struct k v
與lookup
,insert
,update
和delete
,我必須做什麼,使instance At (Struct k v)
工作?
的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
你仍然需要定義IxValue
和Index
型家庭情況:
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.
編輯:其實,在必須返回一個索引鏡頭,而不僅僅是一個鏡頭。我也混淆了二元論的順序。
請注意'透鏡'(或'ilens')通常不是製作鏡片的推薦方法。直接寫入通常會更好。 – shachaf
@shachaf這是爲什麼? – bennofs
它通常更冗長和效率更低(不共享)。 – shachaf