2014-10-21 19 views

risposta

0

Si può solo fare una funzione per sostituire gli elementi:

specialReplace :: Item -> Item -> Item 
specialReplace (X x1) (X x2) = (X x1) 
specialReplace (Y y1) (Y y2) = (Y y1) 
specialReplace _ a = a 

e poi:

foldr (\el list -> map (specialReplace el) list) a b 

verrà eseguito trogolo vostra lista a e applicare le sostituzioni correlate a b conseguenza. Ovviamente se vengono aggiunti più X s o Y nell'elenco b, l'ultimo verrà utilizzato alla fine.

Your live exampleAnother live example

0

primo luogo è necessario un modo per determinare ciò che il costruttore è stato utilizzato:

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 

E un metodo per ottenere il primo valore di ogni tipo di costruttore

import Data.Maybe 

firstX :: [Item] -> Maybe Item 
firstX = listToMaybe . filter isX 

firstY :: [Item] -> Maybe Item 
firstY = listToMaybe . filter isY 

Quindi un modo per sostituire gli articoli

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 

Ma poiché questo è solo una mappa:

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 

E infine non resta che combinare questo con firstX e firstY:

replaceFrom :: [Item] -> [Item] -> [Item] 
replaceFrom a b = 
    let x = firstX b 
     y = firstY b 
    in replaceXY a x y 
0

Per un dato Item e una lista da sostituire, considerare,

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 

in cui ogni schema relativo a ogni t ype in Item. In questo approccio l'ultima occorrenza di ciascun tipo verrà mantenuta nell'elenco sostituito.

2

Prendere in prestito idee da un answer da Petr Pudlak si potrebbe provare:

{-# 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' 

Puoi anche saltare la rimozione dei duplicati in b e utilizzare b al posto di b' nell'ultima riga.

Problemi correlati