dbrattli / Expression

Pragmatic functional programming for Python inspired by F#
https://expression.readthedocs.io
MIT License
421 stars 30 forks source link

seq.map does not type check correctly #167

Closed evanlouie closed 5 months ago

evanlouie commented 11 months ago

Describe the bug

The functional pipe examples where seq.map is the first function in the pipe causes a type error.

To Reproduce Steps to reproduce the behavior:

Screenshot 2023-07-26 at 17 58 18

Expected behavior

pyright type checks correctly

Code or Screenshots

This causes type error:

from expression.collections import seq, Seq

xs = Seq.of(9, 10, 11)
ys = xs.pipe(
    seq.map(lambda x: x * 10),
    seq.filter(lambda x: x > 100),
    seq.fold(lambda s, x: s + x, 0)
)

This passes:

from expression.collections import seq, Seq

xs = Seq.of(9, 10, 11)
ys = xs.pipe(
    seq.filter(lambda x: x > 100),
    seq.map(lambda x: x * 10),
    seq.fold(lambda s, x: s + x, 0)
)

Additional context Add any other context about the problem here.

dbrattli commented 5 months ago

Hi Pyright is unfortunately not good at inferring the types of lambda functions. The problem here is not seq.map nor the pipe method. To fix this (until pyright can infer the types better) you need to assign the lambdas to variables and give them types e.g:

mapper: Callable[[int], int] = lambda x: x * 10
predicate: Callable[[int], bool] = lambda x: x > 100
folder: Callable[[int, int], int] = lambda s, x: s + x

ys = xs.pipe(
    seq.map(mapper),
    seq.filter(predicate),
    seq.fold(folder, 0),
)

I'll update the examples