Function composition with more than 1 parameter

Hi, Is it possible to use function composition with a function that takes more than 1 parameter ? For example, I have a function that finds all the matches of an element within a list :- matches x xs = [ m | m <- xs, x == m ] So, matches 'e' "qwertyee" will return "eee" I now want a function that will work out how many times the element occurs in the list, easily written as :- howMany x xs = length $ matches x xs So, howMany 5 [1,2,3,4,5,5,5,5,5,6,6,6,7] will return 5 However, I'm thinking I want to try to use function composition to write something like :- howMany = length . matches ...which would be nice and clean :) I thought this would work, as the output of matches is a list, and the input required by length is a list. This doesn't work though, failng with the error :- Type error in application *** Expression : length . matches *** Term : length *** Type : [b] -> Int *** Does not match : ([a] -> [a]) -> Int Which I can't quite make out what it means. Ok, it's telling me lengt has a type [b] -> Int which makes sense, but it says it expected a different type, ([a] -> [a]) -> Int What I can't understand is why it wants something of that type ? Is it possibly something to do with the higher precedence of function application over function composition ? I've tried various things, like putting brackets around (length . matches) and changing my function to take in a tuple of (element, list), instead of 2 parameters (which I thought I had working at some stage ! but which now I can't get to work) Any advice appreciated ! thanks :)

You can easily have howMany x = length . matches x I poked around in 'Control.Applicative' (briefly) and didn't find anything that really stood out as answer. -- _jsn

Glurk wrote:
Is it possible to use function composition with a function that takes more than 1 parameter ?
For example, I have a function that finds all the matches of an element within a list :-
matches x xs = [ m | m <- xs, x == m ]
So, matches 'e' "qwertyee" will return "eee"
I now want a function that will work out how many times the element occurs in the list, easily written as :-
howMany x xs = length $ matches x xs
The lambdabot on #haskell has a plugin named "pointless" that can transform this into a definition that doesn't mention x and xs anymore. I think it will propose howMany = (length .) . matches And with matches x xs = filter (x==) xs matches x = filter (x==) matches = filter . (==) we have howMany = (length .) . filter . (==)
I've tried various things, like putting brackets around (length . matches) and changing my function to take in a tuple of (element, list), instead of 2 parameters (which I thought I had working at some stage ! but which now I can't get to work)
howMany = curry (length . uncurry matches) Regards, apfelmus

The lambdabot on #haskell has a plugin named "pointless" that can transform this into a definition that doesn't mention x and xs anymore. I think it will propose
howMany = (length .) . matches
And with
matches x xs = filter (x==) xs
matches x = filter (x==)
matches = filter . (==)
we have
howMany = (length .) . filter . (==)
howMany = curry (length . uncurry matches)
Thanks apfelmus, unfortunately, none of those suggested changes seem to work ! I get errors like :- Unresolved top-level overloading *** Binding : howMany2 *** Outstanding context : Eq b I'm using WinHugs - do you get them to work in some other environment ? Thanks ! :)

Am Samstag, 25. Oktober 2008 12:34 schrieb Glurk:
The lambdabot on #haskell has a plugin named "pointless" that can transform this into a definition that doesn't mention x and xs anymore. I think it will propose
howMany = (length .) . matches
And with
matches x xs = filter (x==) xs
matches x = filter (x==)
matches = filter . (==)
we have
howMany = (length .) . filter . (==)
howMany = curry (length . uncurry matches)
Thanks apfelmus,
unfortunately, none of those suggested changes seem to work ! I get errors like :-
Unresolved top-level overloading *** Binding : howMany2 *** Outstanding context : Eq b
I'm using WinHugs - do you get them to work in some other environment ?
Did you give a type signature for these? Then you would of course have to include the context Eq b, since (==) is used. If you don't give any type signatures, all above versions should work in all environments, otherwise it would be a serious bug.
Thanks ! :)

I'm using WinHugs - do you get them to work in some other environment ?
Did you give a type signature for these? Then you would of course have to include the context Eq b, since (==) is used. If you don't give any type signatures, all above versions should work in all environments, otherwise it would be a serious bug.
OK, now I'm getting somwhere ! :) I tried it with GHCi, and it works ! ...but only after disabling the monomorphism restriction ! It offered another alternative, which was to give a type definition. So, I tried :- matches :: Eq a => a -> [a] -> [a] matches = filter . (==) hm :: Eq a => a -> [a] -> Int hm = (length .) . matches in Hugs, and that also worked :) I'm still struggling to come to grips with how it is actually working... I was thinking that this pointfree style was to make things simpler, more readable and understandable...but now I'm not so sure ! If it's not a simple case (f.g.h etc) I might just stick with putting the parameter names in. At this point, brackets and multiple dots like this don't really make things clearer to me (Not to mention John's post below, with 3 consecutive dots ! I'm really having trouble with that one !). Of course, a lot of this is due to my lack of understanding - I'll keep experimenting and trying to learn :) In general though, do people find this style clearer ? I'd be interested to know what other people prefer. Thanks for all the help :)

Glurk
If it's not a simple case (f.g.h etc) I might just stick with putting the parameter names in. At this point, brackets and multiple dots like this don't really make things clearer to me (Not to mention John's post below, with 3 consecutive dots ! I'm really having trouble with that one !). Of course, a lot of this is due to my lack of understanding - I'll keep experimenting and trying to learn :)
In general though, do people find this style clearer ? I'd be interested to know what other people prefer.
This is also my personal rule. Beyond such simple cases, insisting on point-free programming IMHO does more bad than good by obfuscating the code. See http://haskell.org/haskellwiki/Pointfree#Combinator_discoveries for some clever, if arcane, examples :P

Am Samstag, 25. Oktober 2008 15:57 schrieb Glurk:
I'm using WinHugs - do you get them to work in some other environment ?
Did you give a type signature for these? Then you would of course have to include the context Eq b, since (==) is
used.
If you don't give any type signatures, all above versions should work in all environments, otherwise it would be a serious bug.
OK, now I'm getting somwhere ! :)
I tried it with GHCi, and it works ! ...but only after disabling the monomorphism restriction !
Oh yes, the dreaded MR I forgot.
It offered another alternative, which was to give a type definition.
So, I tried :-
matches :: Eq a => a -> [a] -> [a] matches = filter . (==)
hm :: Eq a => a -> [a] -> Int hm = (length .) . matches
in Hugs, and that also worked :)
I'm still struggling to come to grips with how it is actually working... I was thinking that this pointfree style was to make things simpler, more readable and understandable...but now I'm not so sure !
Sometimes pointfree style is clearer and more readable, sometimes it makes things obscure. Get some experience writing both, pointfree and pointful versions, to develop a feeling when to write pointfree and when not (and when to use mixed style, e.g. "hm x = length . matches x" might be clearer).
If it's not a simple case (f.g.h etc) I might just stick with putting the parameter names in. At this point, brackets and multiple dots like this don't really make things clearer to me (Not to mention John's post below, with 3 consecutive dots ! I'm really having trouble with that one !). Of course, a lot of this is due to my lack of understanding - I'll keep experimenting and trying to learn :)
In general though, do people find this style clearer ? I'd be interested to know what other people prefer.
Thanks for all the help :)
If you compose single-argument functions, the pointfree composition = f . g . h seems clearer than composition x = f . g . h $ x , a case like howMany, howMany = (length .) . matches is sufficiently clear either way (less if written ((.) . (.)) length matches), but beyond that supplying arguments is desirable. Would you prefer to read composition = ((.) . (.) . (.) . (.) . (.)) func thing composition = ((((func .) .) .) .) . thing composition a b c d = func . thing a b c d or composition a b c d e = func $ thing a b c d e ? IMO, the last two are okay, the first is baaad, the second bad unless in special circumstances.

Sometimes pointfree style is clearer and more readable, sometimes it makes things obscure. Get some experience writing both, pointfree and pointful versions, to develop a feeling when to write pointfree and when not (and when to use mixed style, e.g. "hm x = length . matches x" might be clearer).
I think that's good advice :) Having a better understanding of how it works is never a bad thing ! :) I still have trouble understanding a simple one like :- matches = filter . (==) which actually is kind of nice and clean, but when I try to understand it I get confused. In particular I wonder how it "knows" where the parameters go ? (==) is of type (==) :: Eq a => a -> a -> Bool yet I'm giving it incorrect parameters, I'm giving it a [a] not a a (or am I ?) Or, does it take the only valid parameter I give it, the a, and then form a function out of this (a==), and then compose this new function with filter, which does take a function of this new type. Then, there is one parameter left, [a], which is what this new function needs...and so it all works out ! Why doesn't it try to take the 2 parameters for (==), and bomb out when it finds the second parameter is wrong ? Is this where the monomorphism restriction things comes into play ? Or now because I've given it a type, somehow it can now work things out.... ? Does anyone know of a good tutorial on how this all works ? :) Thanks

On 2008 Oct 25, at 18:44, Glurk wrote:
Or, does it take the only valid parameter I give it, the a, and then form a function out of this (a==), and then compose this new function with filter, which does take a function of this new type. Then, there is one parameter left, [a], which is what this new function needs...and so it all works out !
This is it exactly.
Why doesn't it try to take the 2 parameters for (==)
In reality there are no two-parameter functions. They are actually single-parameter functions which return functions. Thus only one argument will ever be consumed by a particular application. Symbolically: (\a b -> f a b) = \a -> (\b -> f a b) taking argument a and returning the function (\b -> f a b) with a having whatever value it was given in the first application (in other languages this is often referred to as a closure). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

Am Sonntag, 26. Oktober 2008 00:44 schrieb Glurk:
Sometimes pointfree style is clearer and more readable, sometimes it makes things obscure. Get some experience writing both, pointfree and pointful versions, to
develop
a feeling when to write pointfree and when not (and when to use mixed style, e.g. "hm x = length . matches x" might be clearer).
I think that's good advice :) Having a better understanding of how it works is never a bad thing ! :)
I still have trouble understanding a simple one like :-
matches = filter . (==)
which actually is kind of nice and clean, but when I try to understand it I get confused. In particular I wonder how it "knows" where the parameters go ?
(==) is of type (==) :: Eq a => a -> a -> Bool
yet I'm giving it incorrect parameters, I'm giving it a [a] not a a (or am I ?)
For any composition f . g, the evaluation goes (f . g) x = f (g x), so (filter . (==)) x = filter ((==) x) Now if x has type a which is an instance of Eq, x is a suitable argument for (==) and ((==) x) has type a -> Bool, hence ((==) x) is a suitable argument for filter, so what happens is exactly what you describe below.
Or, does it take the only valid parameter I give it, the a, and then form a function out of this (a==), and then compose this new function with filter, which does take a function of this new type. Then, there is one parameter left, [a], which is what this new function needs...and so it all works out !
Why doesn't it try to take the 2 parameters for (==), and bomb out when it finds the second parameter is wrong ?
Because as soon as (==) has received its first parameter, the section (a ==) becomes the first argument of filter, so the second argument to (==) is then provided by filter (you remember: filter prd (x:xs) | prd x = x:filter prd xs | otherwise = filter prd xs filter _ [] = [] )
Is this where the monomorphism restriction things comes into play ? Or now because I've given it a type, somehow it can now work things out.... ?
No, strictly speaking, every function has only one argument, it is only a matter of convenience to say that functions which return functions take several arguments. And it's the fact that a function has only one argument which is the reason why it works out.
Does anyone know of a good tutorial on how this all works ? :)
Thanks

Glurk
Type error in application *** Expression : length . matches *** Term : length *** Type : [b] -> Int *** Does not match : ([a] -> [a]) -> Int
Which I can't quite make out what it means. Ok, it's telling me lengt has a type [b] -> Int which makes sense, but it says it expected a different type, ([a] -> [a]) -> Int What I can't understand is why it wants something of that type ?
It's not saying that it wants ([a] -> [a]) -> Int. Rather, it's saying that the type it inferred (([a] -> [a]) -> Int) is not what it wants ([b] -> Int). It expected that a list would be passed to length ([b]). Instead, you pass a function that eats and spews strings ([a] -> [a]) which is the type that matches would have after being partially applied (e.g., matches 'e').
Is it possibly something to do with the higher precedence of function application over function composition ?
I don't think so. You might be confusing the instances of length and matches in your new definition of howMany as function applications. In it, the only function that is getting applied is . which is passed length and matches as arguments.

Glurk, "(.) . (.)" seems to do it: dorsey@elwood:~$ ghci GHCi, version 6.8.3: http://www.haskell.org/ghc/ :? for help Loading package base ... linking ... done. Prelude> let (...) = (.) . (.) Prelude> let matches x xs = [ m | m <- xs, x == m ] Prelude> :t length ... matches length ... matches :: (Eq a) => a -> [a] -> Int Prelude> Regards, John
participants (7)
-
apfelmus
-
Brandon S. Allbery KF8NH
-
Chry Cheng
-
Daniel Fischer
-
Glurk
-
Jason Dusek
-
John Dorsey