
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