Reputation: 161
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
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
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