
Hi. I am kind of tired of all of the parentheses I have to put in places and I'm trying to figure out what is the correct way to write code such that I can leave out parentheses. For example, I have the following: data Message = ... --leaving this out because it's not important data Plane = Plane { id :: Int, position :: (Int,Int,Int), direction :: Int, path :: [Int], messagebuf :: Chan Message } main = do c <- newChan :: Chan Message p <- Plane 0 (0,0,0) 0 [] c f p f p = putStrLn $ (show Main.id p) ++ " - message received" This causes an error "The function `show' is applied to two arguments". If I put instead: f p = putStrLn $ (show . Main.id p) ++ " - message received" I get the error "Couldn't match expected type `[Char]' with actual type `a0 -> c0'". The only way it seems to work is f p = putStrLn $ (show (Main.id p)) ++ " - message received" This seems to be the same for many other situations where I try to use function composition of some sort. It's just getting kind of annoying. -Eitan

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 5/7/11 15:10 , Eitan Goldshtrom wrote:
I get the error "Couldn't match expected type `[Char]' with actual type `a0 -> c0'". The only way it seems to work is f p = putStrLn $ (show (Main.id p)) ++ " - message received"
Interestingly enough, you have the correct answer in there as well: "$"
f p = putStrLn $ (show $ Main.id p) ++ " = message received"
You may also want to look into Control.Applicative. - -- brandon s. allbery [linux,solaris,freebsd,perl] allbery.b@gmail.com system administrator [openafs,heimdal,too many hats] kf8nh -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk3FmykACgkQIn7hlCsL25X9cQCeM2leHUslCJWW1GIFKtt5Dw9P gFoAn1DbWu9QO89062Dx6hMIPRNq6siU =P2Zz -----END PGP SIGNATURE-----

I know about the $ symbol, that's why it's in there in the respective places. I see that I can use it to fix my problem, but I was trying to figure out function composition really. I guess that's just not the place for it. I'll check out Control.Applicative. Also thanks for the clarification on function application. I know functions are by default infixl 9, but I hadn't really thought that through all the way. -Eitan

As another suggestion, you may try HLint [1]. It usually tells you if you put unnecessary parenthesis. Among other nice suggestions. [1] http://community.haskell.org/~ndm/hlint/ (or cabal-install hlint) Cheers, =) -- Felipe.

On 5/7/11 4:29 PM, Eitan Goldshtrom wrote:
I know about the $ symbol, that's why it's in there in the respective places. I see that I can use it to fix my problem, but I was trying to figure out function composition really. I guess that's just not the place for it. I'll check out Control.Applicative. Also thanks for the clarification on function application. I know functions are by default infixl 9, but I hadn't really thought that through all the way.
The "secret" to parentheses in Haskell is that juxtaposition binds most strongly. That's it. Other languages (e.g., Perl, ML) have much more complicated rules which often lead new Haskellers astray; ignore them! Thus, f p = putStrLn $ show (Main.id p) ++ " - message received" Because you are applying Main.id to p, and you are applying show to (Main.id p). Of course, this is identical to: f p = putStrLn (show (Main.id p) ++ " - message received") Since ($) is defined by: f $ x = f x with very low precedence. Alternatively, these are also identical to: f p = putStrLn $ (show . Main.id) p ++ " - message received" f p = putStrLn $ ((show . Main.id) p) ++ " - message received" f p = putStrLn $ (show . Main.id $ p) ++ " - message received" f p = putStrLn ((show . Main.id $ p) ++ " - message received") etc. Note that the definition of (.) is: f . g = \x -> f (g x) or, if you prefer, (f . g) x = f (g x) -- Live well, ~wren

Eitan Goldshtrom wrote:
f p = putStrLn $ (show (Main.id p)) ++ " - message received"
Brandon S Allbery KF8NH wrote:
f p = putStrLn $ (show $ Main.id p) ++ " = message received"
wren ng thornton
f p = putStrLn $ show (Main.id p) ++ " - message received" f p = putStrLn $ (show . Main.id) p ++ " - message received" f p = putStrLn $ ((show . Main.id) p) ++ " - message received" f p = putStrLn $ (show . Main.id $ p) ++ " - message received" f p = putStrLn ((show . Main.id $ p) ++ " - message received") etc.
I think the clearest way to write it is: f = putStrLn . (++ " - message received") . show . Main.id Not because it happens to be point-free, but because it is the "combinator" approach. You apply functions one after the other, each with its own simple meaning and purpose. If I were to describe to someone in words what this function does, I would say something like: "Apply Main.id, turn it into a string, tack a message onto the end, and print it." So why not write it that way in Haskell? One of the nicest features of Haskell is that the combinator approach is often so natural. Regards, Yitz

On 10 May 2011, at 08:30, Yitzchak Gale wrote:
If I were to describe to someone in words what this function does, I would say something like: "Apply Main.id, turn it into a string, tack a message onto the end, and print it." So why not write it that way in Haskell?
Why not indeed ? (-->) = flip (.) f = Main.id --> show --> (++ " = message received") --> putStrLn ;-)
One of the nicest features of Haskell is that the combinator approach is often so natural.
:-) :-)
Regards, Yitz
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-------------------------------------------------------------------- Andrew Butterfield Tel: +353-1-896-2517 Fax: +353-1-677-2204 Foundations and Methods Research Group Director. School of Computer Science and Statistics, Room F.13, O'Reilly Institute, Trinity College, University of Dublin http://www.cs.tcd.ie/Andrew.Butterfield/ --------------------------------------------------------------------

On 10 May 2011 09:47, Andrew Butterfield
Why not indeed ? (-->) = flip (.) f = Main.id --> show --> (++ " = message received") --> putStrLn
-- (>>>) :: Category cat => cat a b -> cat b c -> cat a c import Control.Category ( (>>>) ) f = Main.id >>> show >>> (++ " - message received") >>> putStrLn

Andrew Butterfield wrote:
Why not indeed ?
Roel van Dijk wrote:
import Control.Category ( (>>>) ) f = Main.id >>> show >>> (++ " - message received") >>> putStrLn
Indeed, I agree. I sometimes do that, too, when I want to emphasize the idea of "applying tools one after the other". But most often I just use traditional "function composition" notation. That reminds us of the connection with mathematical functions. It also raises less eyebrows when other people read my code and see

Andrew Butterfield wrote:
Why not indeed ?
Roel van Dijk wrote:
import Control.Category ( (>>>) ) f = Main.id >>> show >>> (++ " - message received") >>> putStrLn
Indeed, I agree. I sometimes do that, too, when I want to emphasize the idea of "applying tools one after the other". But most often I just use traditional "function composition" notation. That reminds us of the connection with mathematical functions. It also raises less eyebrows when other people read my code - some people immediately panic when they see an import from Control.Category or Control.Arrow. :) Regards, Yitz

On 10/05/2011 08:30 AM, Yitzchak Gale wrote:
I think the clearest way to write it is:
f = putStrLn . (++ " - message received") . show . Main.id
You're serious??
If I were to describe to someone in words what this function does, I would say something like: "Apply Main.id, turn it into a string, tack a message onto the end, and print it." So why not write it that way in Haskell?
Hmm, I suppose. OTOH, this breaks if you want to insert several items into a string. For example, f x y z = putStrLn ("X = " ++ show x ++ ", Y = " ++ show y ++ ", Z = " ++ show z) (Fortunately, here a simple call to ($) will fix you up nicely.)

On Sat, May 7, 2011 at 2:10 PM, Eitan Goldshtrom
Hi. I am kind of tired of all of the parentheses I have to put in places and I'm trying to figure out what is the correct way to write code such that I can leave out parentheses. For example, I have the following:
data Message = ... --leaving this out because it's not important data Plane = Plane { id :: Int, position :: (Int,Int,Int), direction :: Int, path :: [Int], messagebuf :: Chan Message }
main = do c <- newChan :: Chan Message p <- Plane 0 (0,0,0) 0 [] c f p
f p = putStrLn $ (show Main.id p) ++ " - message received"
One thing to keep in mind is that function application binds tightest, and function application goes from left to right, so:
a b c d
is parsed as:
((a b) c) d
I'm not really sure what you're doing, but I would probably write it as:
f p = putStrLn $ show (Main.id p) ++ " - message received"
Because function application binds tightest, I don't need parenthesis around the (show ...) part. The other rule to note is the the ($) function binds the weakest of them all, so you can do a lot to the left of it and to the right of it without parentheses.
This causes an error "The function `show' is applied to two arguments". If I put instead: f p = putStrLn $ (show . Main.id p) ++ " - message received"
I get the error "Couldn't match expected type `[Char]' with actual type `a0 -> c0'". The only way it seems to work is f p = putStrLn $ (show (Main.id p)) ++ " - message received"
This seems to be the same for many other situations where I try to use function composition of some sort. It's just getting kind of annoying.
-Eitan
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (9)
-
Andrew Butterfield
-
Andrew Coppin
-
Antoine Latter
-
Brandon S Allbery KF8NH
-
Eitan Goldshtrom
-
Felipe Almeida Lessa
-
Roel van Dijk
-
wren ng thornton
-
Yitzchak Gale