# Statically-typed functional lists in Python with Mypy

July 21, 2015

Let's implement some functional list functions in Python, using Mypy to annotate and enforce types.

lists.py:

Import some goodies from Mypy's `typing` module, and Python's `functools` module:

``````from typing import TypeVar, Generic, List, Callable
from functools import reduce # type: ignore (see github.com/JukkaL/mypy/issues/500)``````

Declare a couple of variables:

``````A = TypeVar('A')
B = TypeVar('B')``````

Let's get functional:

``````def fmap(f: Callable[[A], B], xs: List[A]) -> List[B]:
return list(map(f, xs))

def flatten(xs: List[List[A]]) -> List[A]:
return reduce(lambda a, b: a + b, xs)

def flatMap(f: Callable[[A], List[B]], xs: List[A]) -> List[B]:
return flatten(fmap(f, xs))``````

Type-check it with Mypy:

``````\$ mypy lists.py
\$ echo \$?
0``````

No errors -- it compiles! Let's take it for a spin.

demo.py:

``````from lists import fmap, flatMap

xs = [1, 2, 3]

ys =    fmap(lambda x:  x * 2, xs) # [2, 4, 6)
zs = flatMap(lambda x: [x, x], xs) # [1, 1, 2, 2, 3, 3]

print(ys) # [2, 4, 6]
print(zs) # [1, 1, 2, 2, 3, 3]``````

Run it with Python:

``````\$ python3 demo.py
[2, 4, 6]
[1, 1, 2, 2, 3, 3]``````