Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace items from a list with items with matching constructors in another list

Tags:

haskell

To simplify the problem I'm facing, assume this data type:

data Item = X Int | Y Char deriving (Eq, Show..)

and two lists

let a = [X 1, Y 'g']
let b = [X 2]

I need to replace all items in a with the first (or any) item in b with the same constructor. So the result would be: [X 2, Y 'g'].

Any suggestions?

like image 620
dan Avatar asked Oct 21 '14 16:10

dan


1 Answers

Borrowing ideas from an answer by Petr Pudlák you could try:

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

You can also skip removing the duplicates in b and use b instead of b' in the last line.

like image 180
j.p. Avatar answered Oct 11 '22 13:10

j.p.