Haskell function composition

178 views Asked by At

I've defined a function f1 and f2,so that I can use at the and the function composition (fkomp), which is supposed to use f1 and f2 to calculate 2^x by every element in a given List.

f1 :: Int -> Int 
f1 x = product (replicate x 2)

f2 :: (a -> b) -> [a] -> [b]
f2 f xs = [f x | x <- xs]

fkomp :: [Int] -> [Int]        
fkomp xs = f2 f1 $ xs 

It works,but the problem is,that i can't write my code with composition:

fkomp xs = f2.f1 $ xs

I've been typing every single combination but it doesn't work with composition.

Could someone lighten my path ?

Thanks a lot

1

There are 1 answers

1
Random Dev On BEST ANSWER

Ok, let's look just at the types (it's like a puzzle - the types have to fit):

f1 :: Int -> Int
f2 :: (a -> b) -> [a] -> [b] = (a -> b) -> ([a] -> [b])

in order to compose the both you need ones co-domain to be the same as the others domain.

This is because the composition has type:

(.) :: (b -> c) -> (a -> b) -> a -> c

See the b has to fit ;)

So for your f1 and f2 you would need either Int ~ (a -> b) or Int ~ ([a] -> [b]) both of which are not working well (as you found out).

BUT you kind of have the ability to apply f1 to f2 as f1 just fits f2 first argument (as you have seen too) - so I am a bit confused why you even want to use composition here.

remarks

your functions are a bit strange - I think the usual way to write them would be

f1 x = 2 ^ x
f2 = map

or even

fkomp :: [Int] -> [Int]
fkomp = map (2^)

note that the last one is not function-composition but (just as your case) function-application: I apply the function (2^) :: Int -> Int to map :: (Int -> Int) -> [Int] -> [Int] and get a function of type [Int] -> [Int] as the result (if you check the types in GHCi you will see a more generic versions but I think this is a bit more clear)