First you need a way to determine which constructor was used:
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
And a method to get the first value of each type of constructor
import Data.Maybe firstX :: [Item] -> Maybe Item firstX = listToMaybe . filter isX firstY :: [Item] -> Maybe Item firstY = listToMaybe . filter isY
Then you can replace the items
replaceItem :: Item -> Maybe Item -> Item replaceItem = fromMaybe replaceItems :: [Item] -> Maybe Item -> Maybe Item -> [Item] replaceItems [] _ _ = [] replaceItems (item:items) xy = (if isX item then replaceItem item x else replaceItem item y) : replaceItems items xy
But since this is just a map:
replaceXY :: Item -> Maybe Item -> Maybe Item -> [Item] replaceXY item xy = if isX item then replaceItem item x else replaceItem item y replaceItems items xy = map (\item -> replaceXY item xy) items
And finally, you just need to combine this with firstX and firstY :
replaceFrom :: [Item] -> [Item] -> [Item] replaceFrom ab = let x = firstX b y = firstY b in replaceXY axy
source share