Najpierw musisz sposób ustalić, co konstruktor został użyty:
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
i sposób, aby uzyskać pierwszą wartość każdego rodzaju konstruktora
import Data.Maybe
firstX :: [Item] -> Maybe Item
firstX = listToMaybe . filter isX
firstY :: [Item] -> Maybe Item
firstY = listToMaybe . filter isY
Następnie sposób na wymianę przedmiotów
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
Ale ponieważ jest to tylko mapa:
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
I wreszcie po prostu trzeba połączyć to z firstX
i firstY
:
replaceFrom :: [Item] -> [Item] -> [Item]
replaceFrom a b =
let x = firstX b
y = firstY b
in replaceXY a x y