In Haskell I would write:
main = do mapM_ print . map (\x -> x^2) . filter (\x -> (mod x 2) == 0) $ [1..20]
in Python I would have to use either many brackets or useless variables ... is there anything like .
and $
in Python?
(I'm not familiar with Haskell, but if I understand your code snippet correctly...)
You can use a list comprehension to perform the filtering and exponentiation.
[i**2 for i in range(1,21) if i%2 == 0]
I would just use whatever idiomatic Python tools are available, such as list comprehensions, as others have pointed out, instead of trying to pretend you're writing Haskell, but if you really must, you could use compose
combinator function even in Python:
# this is essentially just foldr (or right `reduce`) specialised on `compose2`
def compose(*args):
ret = identity
for f in reversed(args):
ret = compose2(f, ret)
return ret
def identity(x): return x
def compose2(f, g): return lambda x: f(g(x))
which you could use like this:
from functools import partial
# equiv. of: map (\x -> x^2) . filter (\x -> (mod x 2) == 0) $ [1..20]
compose(partial(map, lambda x: x**2), partial(filter, lambda x: x % 2 == 0))(range(1, 21))
which admittedly does work:
>>> compose(partial(map, lambda x: x**2), partial(filter, lambda x: x % 2 == 0))(range(1, 21))
[4, 16, 36, 64, 100, 144, 196, 256, 324, 400]
...but as you can see, Python lacks certain concepts such as currying and arbitrarily definable infix operators, so even though semantically, the above snippet of code is equivalent (even identical) to the Haskell snippet, it reads quite hellish.
As to the $
operator: it has little relevance in Python — its primary purpose in Haskell is related to operator precedence, which is a non-issue in Python because you can't really use operators most of the time anyway, and all of the built-in operators have predefined precedence.
And whereas $
can additionally be used as a higher order function in Haskell:
zipWith ($) [(3*), (4+), (5-)] [1,2,3]
...replicating this in Python with its (deprecated) apply
"combinator" will, again, lead to code that is just ugly:
>>> list(starmap(apply, zip([lambda x: 3 * x, lambda x: 4 + x, lambda x: 5 - x], map(lambda x: [x], [1, 2, 3]))))
[3, 6, 2]
— again, several fundamental limitations of Python are at play here:
list()
, you don't get a "normal" list back;(a -> b) -> a -> b
but (a1 -> a2 -> ... -> aN -> b) -> (a1, a2, ..., aN) -> b
, so you need to wrap the list elements with []
and use starmap
not the normal map
; this is also a result of the lack of currying;map
, reduce
, and so on;If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With