为了简化我面临的问题,假设这种数据类型:
data Item = X Int | Y Char deriving (Eq, Show..)
和两个列表
let a = [X 1, Y 'g']
let b = [X 2]
我需要将a
中的所有项目替换为b
中具有相同构造函数的第一个(或任何)项目。结果将是:[X 2, Y 'g']
。
有什么建议吗?
答案 0 :(得分:2)
借用PetrPudlák的answer借用你的想法,你可以试试:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Function (on)
import Data.List (nubBy, find)
import Data.Maybe (fromMaybe)
data Item = X Int | Y Char
deriving (Eq, Show, Typeable, Data)
a = [X 1, Y 'g']
b = [X 2]
main :: IO ()
main = print $ map replace a
where b' = nubBy (on (==) toConstr) b -- remove duplicates
replace x = fromMaybe x $ find (on (==) toConstr x) b'
您也可以跳过删除b中的重复项,并在最后一行使用b代替b'。
答案 1 :(得分:0)
您可以创建一个替换项目的功能:
specialReplace :: Item -> Item -> Item
specialReplace (X x1) (X x2) = (X x1)
specialReplace (Y y1) (Y y2) = (Y y1)
specialReplace _ a = a
然后:
foldr (\el list -> map (specialReplace el) list) a b
将通过您的a
列表运行并相应地应用b
中的相关替换。当然,如果在X
列表中引入了更多Y
或b
s,那么最后一个将在最后使用。
答案 2 :(得分:0)
首先,您需要一种方法来确定使用了哪种构造函数:
isX :: Item -> Bool
isX (X _) = True
isX _ = False
-- If you have more than 2 constructors you'll have to write them all like isX
isY :: Item -> Bool
isY = not . isX
获取每种构造函数的第一个值的方法
import Data.Maybe
firstX :: [Item] -> Maybe Item
firstX = listToMaybe . filter isX
firstY :: [Item] -> Maybe Item
firstY = listToMaybe . filter isY
然后一种替换物品的方法
replaceItem :: Item -> Maybe Item -> Item
replaceItem = fromMaybe
replaceItems :: [Item] -> Maybe Item -> Maybe Item -> [Item]
replaceItems [] _ _ = []
replaceItems (item:items) x y =
(if isX item
then replaceItem item x
else replaceItem item y) : replaceItems items x y
但是因为这只是一张地图:
replaceXY :: Item -> Maybe Item -> Maybe Item -> [Item]
replaceXY item x y =
if isX item
then replaceItem item x
else replaceItem item y
replaceItems items x y = map (\item -> replaceXY item x y) items
最后,您只需将其与firstX
和firstY
:
replaceFrom :: [Item] -> [Item] -> [Item]
replaceFrom a b =
let x = firstX b
y = firstY b
in replaceXY a x y
答案 3 :(得分:0)
对于给定的Item
和要替换的列表,请考虑
replace' :: Item -> [Item] -> [Item]
replace' _ [] = []
replace' (X i) ((X j):xs) = (X i) : replace' (X i) xs
replace' (Y i) ((Y j):xs) = (Y i) : replace' (Y i) xs
replace' r (x:xs) = x : replace' r xs
其中每个模式与Item
中的每种类型相关。在这种方法中,每种类型的最新出现将保留在替换列表中。