Python: Haskell-like./$

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 a plurality of staples or useless variables ... is there something like .and $in Python?

+4
source share
5 answers

I would just use any idiomatic Python tools available , such as list comprehension, as others have pointed out, rather than trying to pretend that you are writing Haskell, but if you really need to, you can use the combinator function composeeven 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 can use as follows:

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))

, , :

>>> 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]

... , , Python , currying infix, , ( ) Haskell, .


$:, Python - Haskell , Python, , .

$ Haskell:

zipWith ($) [(3*), (4+), (5-)] [1,2,3]

... Python () apply "combinator", , :

>>> 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]

- , Python:

  • laziness , , , "" starmap list() "" ;
  • apply (a -> b) -> a -> b, (a1 -> a2 -> ... -> aN -> b) -> (a1, a2, ..., aN) -> b, [] starmap map; ;
  • lambda , Guido lambdas, map, reduce ..;
+3

( Haskell, ...)

.

[i**2 for i in range(1,21) if i%2 == 0]
+5

( - , Python , Haskell), , , :

# Python
for xsquared in [x**2 for x in range(1, 21) if x % 2 == 0]:
    print(xsquared)
# legal, but not idiomatic; you don't construct a list just
# to throw it away.
# map(print, [x**2 for x in range(1, 21) if x % 2 == 0])

-- Haskell
main = (mapM_ print) [ x^2 | x <- [1..20], x `mod` 2 == 0 ]

:

# Python
for xsquared in [x**2 for x in range(2, 21, 2)]:
    print(xsquared)

-- Haskell
main = (mapM_ print) [x^2 | x <- [2,4..20]]

Python , Haskell. Haskell . , f . g , f g. Python ( 3.5, , ).

, Python ( currying), - , . , g . f ∘ g ( , - , Unicode-) f(g(...)) f(*g(...))? "" . , g f? f? , g? , Python.


, , , . , , Python , Haskell , f . g \x -> f (g x). , Python

def f(x):
    return x + 5

def g(x):
    return 3 * x

, f∘g

def fg(x):
    return f(g(x))

, , , Haskell :

def fg(x):
    return 3*x + 5
+2

, , @CoryKramer.

Python, functools.partial, -

from functools import partial
def compose(func1, *func2):
    return func1 if not func2 else lambda x: func1(compose(*func2)(x))

myMap = partial(map, lambda x: x**2)
myFilter = partial(filter, lambda x: x%2 == 0)

myFunction = compose(myMap, myFilter)

myFunction(range(20))
+1

Since the map function returns a list that is iterable and filters, you can also nest them -

map(function1, (filter(function2,list)))

For more information, I would recommend that you read the documentation on the map functions and the documentation on the filter functions.

0
source

Source: https://habr.com/ru/post/1613487/


All Articles