Dominik
Dominik

Reputation: 161

Getting a function from a list of tuples

Given a list of tuples, for example x = [(1,2),(2,3),(3,1)] I want to extract the function which maps 1 to 2, 2 to 3 and 3 to 1 (i.e. I want to construct a function from its set theoretic definition).
So far I constructed the following to define a function from a tuple

mfromt :: (Int,Int) -> (Int -> Int)  
mfromt (a,b) = f where  
    f x  
    | x == a = b

but I have no idea how to generalize this to a list of tuples, I would need some way of combining partially defined functions. But I have the strong feeling that there should be a better solution anyway.

Upvotes: 1

Views: 67

Answers (2)

SergeyKuz1001
SergeyKuz1001

Reputation: 875

Maybe lookup is function you need:

lookup :: Eq a => a -> [(a, b)] -> Maybe b

But it return Maybe b type because corresponding pair may not be in input list.

Upvotes: 3

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476659

We can implement this as a cascade where if a function fails, we go to the next function. So for the given list of tuples, we can implement this as:

f0 :: Int -> Int
f0 = error "variable out of range"

f1 :: Int -> Int
f1 x
  | x == 1 = 2
  | otherwise = f2 x


f2 :: Int -> Int
f2 x
  | x == 2 = 3
  | otherwise = f2 x


f3 :: Int -> Int
f3 x
  | x == 3 = 1
  | otherwise = f2 x

Now of course here we hardcode the values. We can however implement a function that makes such f through parameters, so:

genF :: Int -> Int -> (Int -> Int) -> (Int -> Int)
genF x y f x0
  | x0 == x = y
  | otherwise = f x

Finally we can make use of foldr (or foldl) to construct such function per 2-tuple in the list. This will thus look like:

mfromt :: [(Int, Int)] -> Int -> Int
mfromt fs = foldr (…) (error "variable out of range") fs

where I leave implementing as an exercise. This function has as type … :: (Int, Int) -> (Int -> Int) -> (Int -> Int) and thus should use the genF function.

Upvotes: 1

Related Questions