Skip to content

Kinded type behaving differently from non-kinded type in an invariant wrapper #2042

Description

@pradeep90

Hi Nikita, long time! Thanks for the interesting library bringing Haskell-like FP patterns to Python.

Bug report

What's wrong

I'm trying to extract the type T from a Kind1 type (say, Foo[T]) that is wrapped in an invariant type, e.g., list[Foo[T]]. However, that's leading to some unexpected behavior.

Repro:

from typing import Any, TypeVar

from returns.primitives import hkt

T = TypeVar("T")


class Foo(hkt.SupportsKind1["Foo[Any]", T]):
    pass


# These are just helper functions to extract the type `T`.
def expect_list_foo(foo_list: list[Foo[T]]) -> list[T]:
    return []


@hkt.kinded
def expect_list_foo__kinded(foo_list: list[hkt.Kind1[Foo[Any], T]]) -> list[T]:
    return []


@hkt.kinded
def expect_tuple_foo__kinded(foo_tuple: tuple[hkt.Kind1[Foo[Any], T], str]) -> list[T]:
    return []


def inferred_types(foo_list: list[Foo[int]], foo_tuple: tuple[Foo[int], str]) -> None:
    x = expect_list_foo(foo_list)

    y = expect_list_foo__kinded(foo_list)  # <-- Problem

    z = expect_tuple_foo__kinded(foo_tuple)

    reveal_type(x)
    reveal_type(y)
    reveal_type(z)

    print(x, y, z)

How is that should be

I expected all three calls to work and return list[int].

Actual output:

30: error: Argument 1 to "expect_list_foo__kinded" has incompatible type "list[Foo[int]]"; expected "list[KindN[Foo[Any], int, Any, Any]]"  [arg-type]
30: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
30: note: Consider using "Sequence" instead, which is covariant
34: note: Revealed type is "builtins.list[builtins.int]"
35: note: Revealed type is "builtins.list[builtins.int]"
36: note: Revealed type is "builtins.list[builtins.int]"
Found 1 error in 1 file (checked 1 source file)

Seems like list[Foo[int]] is not treated as compatible with list[hkt.Kind1[Foo[Any], T]]. tuple[Foo[int], str] is treated as compatible with tuple[hkt.Kind1[Foo[Any], T], str]. So, it seems like this might be due to the invariance of list.

Is this expected behavior? How can I get this to work?

System information

  • python version: 3.10.8

  • returns version: 0.24.0

  • mypy version: 1.15.0

  • hypothesis version (if any):

  • pytest version (if any):

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions