2014-10-21 5 views

Odpowiedz

0

Można po prostu zrobić funkcję, aby zastąpić elementy:

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

a następnie:

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

potrwa koryta listę a i zastosować skorelowanych podstawienia w b odpowiednio. Oczywiście, jeśli więcej X s lub Y s są wprowadzone na liście b, to ostatni będzie używany na końcu.

Your live exampleAnother live example

0

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 
0

Dla danego Item i liście, która zostanie zastąpiona rozważ,

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 

w którym każdy wzór związany z każdym t Ype w Item. W tym podejściu najnowsze występowanie każdego typu będzie zachowane na wymienionej liście.

2

Wypożyczenie pomysły z answer Petr Pudlák można spróbować:

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

Można również pominąć usuwanie duplikatów w B i używać zamiast b b”w ostatnim wierszu.

Powiązane problemy