我有以下關聯串列:
myList :: [(myConcept, String)]
myList = [
(myInput, "get_input"),
(myOutput, "get_output"),
(myValues, "get_values")]
-- | Data type
data myConcept = myInput | myOutput | myValues deriving Eq
如果添加條目,我想確保串列沒有任何沖突的條目。如何才能做到這一點?是否可以使用串列 Map myConcept String 來避免條目沖突?
編輯:
我可以使用以下功能來防止鍵沖突,但我也想防止值沖突。
addOrReplace :: Eq k => k -> v -> [(k, v)] -> [(k, v)]
addOrReplace key value list = (key,value):(filter ((key /=).fst) list)
我了解遞回檢查串列,但是如何檢查關聯串列中一對的值?
checkValue :: Eq v => v -> [(k, v)] -> Bool
checkValue :: value [] = False
checkValue :: value [x] = check value of this entry?
checkValue :: value [x:xs]
| check value of this entry?
| otherwise = checkValue value xs
上面的另一個問題是,使用 [x:xs] 它將回傳 False 并且不檢查串列的其余部分。如何在“如果為假,請繼續檢查串列”的情況下添加 if 條件?
uj5u.com熱心網友回復:
import qualified Data.Map as MAP
import Data.Maybe
import qualified Data.Bimap as BIMAP
data MyConcept = MyInput | MyOutput | MyValues deriving Eq
myList :: [(MyConcept, String)]
myList = [
(MyInput, "get_input"),
(MyOutput, "get_output"),
(MyValues, "get_values")]
開始:您的固定 checkValue 功能:
checkValue :: Eq v => v -> [(k, v)] -> Bool
checkValue str [] = False
checkValue str ((t,v):xs)
| str == v = True
| otherwise = checkValue str xs
您必須問自己的一般問題:條目對于 MyConcept 是否應該是唯一的:
(a) 應該允許 [(MyInput, "value1"), (MyInput, "value2")] 嗎?
我假設:
(b) MyValues 是唯一可以保存實際值的識別符號
-> 否則只檢查值(=字串部分)是沒有意義的......
選項 1.1:地圖假設 (a) 是不允許的:
-- additionally needed:
instance Ord MyConcept where
compare m1 m2
| m1 == m2 = EQ
| otherwise = LT -- not good but practical
type List_Map1 = MAP.Map MyConcept (MyConcept, String)
add1 :: String -> List_Map1 -> List_Map1
add1 str list = if isNothing value
then MAP.insert MyValues (MyValues, str) list
else error "insert here your prefered runtime error message"
where
value = MAP.lookup MyValues list
選項 1.2:地圖假設 (a) 是允許的:
type List_Map2 = MAP.Map String (MyConcept, String)
add2 :: String -> List_Map2 -> List_Map2
add2 str list = if isNothing value
then MAP.insert str (MyValues, str) list
else error ""
where
value = MAP.lookup str list
選項 2:BiMap
type List_Bimap = BIMAP.Bimap MyConcept (MyConcept, String)
add3 :: String -> List_Bimap -> List_Bimap
add3 str list
| isNothing value = BIMAP.insert MyValues (MyValues, str) list
| str == snd (fromJust value) = error "insert here your prefered runtime error message"
-- Change next line to allow (a)
| otherwise = error "insert here your prefered runtime error message"
where
value :: Maybe (MyConcept, String)
value = BIMAP.lookup MyValues list
最后,如果您更喜歡簡單的串列作為輸出:
list1 :: String -> List_Map1 -> [(MyConcept, String)]
list1 s l = map snd $ MAP.toList $ add1 s l
list2 :: String -> List_Map2 -> [(MyConcept, String)]
list2 s l = map snd $ MAP.toList $ add2 s l
list3 :: String -> List_Bimap -> [(MyConcept, String)]
list3 s l = map snd $ BIMAP.toList $ add3 s l
uj5u.com熱心網友回復:
我懷疑Bimap可以為您提供幾乎所有您想要的東西。您可能必須撰寫一個小型包裝器來在重復條目上引發運行時錯誤(而不是覆寫),但這應該不會太難。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/465874.html
標籤:哈斯克尔
