function application

Hi, I’m looking at mc :: (Integral a) => a -> a mc x | x > 100 = x - 10 | otherwise = mc ( mc ( x + 11 ) ) the mc ( mc ( x + 11 ) ) can also be written as mc . mc $ x + 11 and I expected it could also be written as mc . mc ( x + 11 ) but the compiler error starts off with Couldn't match expected type ‘a’ with actual type ‘a0 -> c0’ so that is telling me, isn’t it (?) , that using parens is making the argument to the second mc into a function ‘a0 -> c0’ So is mc . mc $ x + 11 the only correct way to write this particular function in ‘.’ style ? Many Thanks Mike

On Sun, Apr 10, 2016 at 05:16:24PM +0100, mike h wrote:
So is mc . mc $ x + 11
the only correct way to write this particular function in ‘.’ style ?
Hello Mike, (mc . mc) (x + 11) would do too. Remember, function application (white-space) takes precedence over *everything*, so: mc . mc ( x + 11 ) ^ ^ | +------- whitespace | +----------- operator is the same as: mc . (mc ( x + 11 ))

Mike: If you seek as I think you do, to write the function mc (partially) in point-free style, you must know this style implies no arguments, or at least not all arguments, mentioned, that is for example here: mc x | x < 100 = x - 10 mc = mc . mc . (+ 11) The second line will only be checked for pattern matching if the first one fails, so it amounts to the "otherwise" guard as here there's no pattern, so it's a bit like the pattern that always matches (mc _ = ...) You'll remark I did write (mc =) and not (mc x =). Point free style amounts to describing a function through a composition of other functions, in an arguments-free way, here for example, (mc . mc . (+11)) being the composition of mc twice, with the "partially-applied" function (+11) == (\x -> x + 11) == (11+). This partially applied notation works for all operators by the way. And for the record, the whitespace operator is a pure myth. First you can remove all whitespace, it still works. Second, try using the same whitespace-induced universal right-associativity with (f a b): does it amount to (f (a b))? The reason for this right-associativity interpretation in (mc . mc (x + 11)) is because (.) itself is right associative: right-directed greediness could we say, in the vocabulary of regular expression. It's also the case of ($), and that's why we use it to counter the natural left associativity of function application: f $ g a == f $ (g a) == ($) f (g a) == f (g a) -- (using the definition of ($) here) instead of f g a == (f g) a without using ($). The whitespace is just a meaningless character (I guess, a set of characters) used to separate juxtaposed meaningful tokens of the language when we have either (symbol,symbol) or (nonsymbol,nonsymbol), for example respectively (!! $ /= !!$) and (f g /= fg). whenever it's a nonsymbol and a symbol, whitespace is not necessary (a+, +a). Then there's the automatic, implicit function application between two juxtaposed non-symbolic tokens. But the whitespace has never been an operator of any kind, and is totally meaningless (and optional) in (mc . mc (x + 11)). Especially too, it's clear no whitespace survives the tokenization during the lexical phase of the (pre?) compilation, contrarily to all real operators like (+).

Hi,
Thanks for the comprehensive and considered answers. Maybe I'm missing something but defining the original function to have two definitions with a different number of args in each causes a compiler error ie. doing
mc :: (Integral a) => a -> amc x | x < 100 = x - 10 -- 1 arg
mc = mc . mc . (+ 11) -- no args
Thanks
On Sunday, 10 April 2016, 22:29, Silent Leaf

true! no it's totally my fault, i forgot about that. I'm not exactly sure
why is that, it seems slightly absurd, limiting, to me but I guess it must
be something on the inside.
In that case, from what I know to this day, you'll have to choose either,
and I know no easy way to integrate a point-free conditional choice (in
other terms, to replace the guards in a pointfree manner) on one of the
parameters, so I'd go for the non-pointfree style, aka your original
implementation, with the guards.
of course we can merrily cheat:
test1arg :: (a -> b) -> (a -> b) -> (a -> Bool) -> a -> b
test1arg cond thenF elseF x
| cond x = thenF x
| otherwise = elseF x
then:
mc :: Integral a => a -> a
mc = test1arg (<100) (-10) (mc . mc . (+11))
it amounts to moving the guards into another function. the "if then else"
expression is very similar of course, but doesn't allow, as far as I know,
point-free style.
Anyway... all this becomes a pointless (pun unintended) search for the
point-free style at all costs. I'm not sure it's generally speaking, a very
good idea. Non-point-free style is perfectly good style in itself, and
pointfree should be in my opinion reserved to cases where it comes
naturally, where, when perhaps looking at one's definition for a function,
one realizes the presence of the argument is pointless; one very random
last-minute example:
f xs = zip [0..] xs ---> f = zip [0..]
also to the cases when the very definition of a function comes to one as
combination of other functions. beyond that, I'd say it's mostly wasted
time.
I think the question is to balance the style, to always prefer clarity to
"coolness" at any rate. Sure, in many cases, a pointfree style is in my
opinion much quicker to understand, much clearer. Also, pointfree style is
also a very good exercise I think, that permits beginners (i put myself in
it needless to say) to get a better understanding of haskell's syntax, and
of the whole function paradigm in general.
As long as exercises in pointfree feats aren't hindering real programming,
I'd say there's no problem in trying to go for it whenever it's possible.
Plus in my opinion it can be fun.
2016-04-11 16:16 GMT+02:00 mike h
Hi,
Thanks for the comprehensive and considered answers. Maybe I'm missing something but defining the original function to have two definitions with a different number of args in each causes a compiler error ie. doing
mc :: (Integral a) => a -> amc x | x < 100 = x - 10 -- 1 arg mc = mc . mc . (+ 11) -- no args
Thanks
On Sunday, 10 April 2016, 22:29, Silent Leaf
wrote: Mike: If you seek as I think you do, to write the function mc (partially) in point-free style, you must know this style implies no arguments, or at least not all arguments, mentioned, that is for example here: mc x | x < 100 = x - 10 mc = mc . mc . (+ 11)
The second line will only be checked for pattern matching if the first one fails, so it amounts to the "otherwise" guard as here there's no pattern, so it's a bit like the pattern that always matches (mc _ = ...) You'll remark I did write (mc =) and not (mc x =). Point free style amounts to describing a function through a composition of other functions, in an arguments-free way, here for example, (mc . mc . (+11)) being the composition of mc twice, with the "partially-applied" function (+11) == (\x -> x + 11) == (11+). This partially applied notation works for all operators by the way.
And for the record, the whitespace operator is a pure myth. First you can remove all whitespace, it still works. Second, try using the same whitespace-induced universal right-associativity with (f a b): does it amount to (f (a b))?
The reason for this right-associativity interpretation in (mc . mc (x + 11)) is because (.) itself is right associative: right-directed greediness could we say, in the vocabulary of regular expression. It's also the case of ($), and that's why we use it to counter the natural left associativity of function application: f $ g a == f $ (g a) == ($) f (g a) == f (g a) -- (using the definition of ($) here) instead of f g a == (f g) a without using ($).
The whitespace is just a meaningless character (I guess, a set of characters) used to separate juxtaposed meaningful tokens of the language when we have either (symbol,symbol) or (nonsymbol,nonsymbol), for example respectively (!! $ /= !!$) and (f g /= fg). whenever it's a nonsymbol and a symbol, whitespace is not necessary (a+, +a). Then there's the automatic, implicit function application between two juxtaposed non-symbolic tokens. But the whitespace has never been an operator of any kind, and is totally meaningless (and optional) in (mc . mc (x + 11)).
Especially too, it's clear no whitespace survives the tokenization during the lexical phase of the (pre?) compilation, contrarily to all real operators like (+).
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

I agree. I'm just seeing how far point free can be taken under different circumstances.
Thanks for all your comments, much appreciated.
Mike
On Tuesday, 12 April 2016, 0:52, Silent Leaf
participants (3)
-
Francesco Ariis
-
mike h
-
Silent Leaf