Your example can be written more clearly (IMO) in Haskell like this: sum $ map (^2) $ filter odd [1..10]
Or, defined as a function: > let foo = sum . map (^2) . filter odd
> foo [1..10]
165
You can write it without using the composition operator at all, if you prefer: > let bar xs = sum (map (^2) (filter odd xs))
> bar [1..10]
165
In general, you can write out your programs as crazy sequences of operators (whose precedence may not be obvious to the reader): > take 5 . unfoldr (Just . next) <$> getStdGen >>= putStrLn . show
[1336079013,234736121,108049288,410228860,1573295749]
But you don't have to: > let infiniteRandoms = unfoldr (Just . next) :: StdGen -> [Int]
> gen <- getStdGen
> let fiveRandoms = take 5 (infiniteRandoms gen)
> putStrLn (show fiveRandoms)
[1336079013,234736121,108049288,410228860,1573295749]
People seem to think Haskell is all about writing your whole program in a single hideous line of code with incomprehensible sequences of arcane operators glued together by a glut of anonymous functions, but that's just bad code.As for left-to-right vs right-to-left, I have never had a problem with the way Haskell does it. I think if you're coming from a language that does it differently, it makes sense that Haskell would trip you up in that regard. Haskell's composition operator matches the way it's usually written in mathematics, but there's nothing special about it and you could change it to go the other way if you really wanted to (but please don't): > let g . f = \x -> f (g x)
> let foo = filter odd . map (^2) . sum
> foo [1..10]
165
`(>>>)` from `Control.Arrow` is a more reasonable way to get that sweet left-to-right action but using it might still throw people off: > let foo = filter odd >>> map (^2) >>> sum
> foo [1..10]
165
|
In math, the preferred way of writing functions is via composition, as then it enables tools of visualization such as commutative diagrams. One thing to note is that in general mathematicians have a history of picking the right choice in notations for thinking about abstractions at an intuitive level in the world of mathematics (when there is a choice and it matters), and IMO they were correct about how they chose to represent function composition, although it is not immediately obvious unless you start talking about function domains and ranges - the composition notation matches the flow of reading how functions map values from one set to another.
That Clojure version reads like a complete mess to me personally.