了解类型注释中的类型变量

问题描述 投票:3回答:1

Elm docs说明了这样的类型变量:

> List.reverse
<function> : List a -> List a

...类型变量a可以根据List.reverse的使用方式而变化。但是在这种情况下,我们在参数和结果中都有一个“ a”。这意味着,如果您提供List Int,则还必须获得List Int。

Maybe.map的文档显示此注释:

map : (a -> b) -> Maybe a -> Maybe b

因此,当类型必须为相同类型时,为什么将其标注为ab?我希望a可以跟踪类型,即:

map : (a -> a) -> Maybe a -> Maybe a
types elm parametric-polymorphism type-variables
1个回答
5
投票

为什么当类型必须为相同类型时,为什么将其标注为ab

他们不!如果map确实对输入参数类型和返回类型使用相同的类型变量,则它们会使用,但是map可以从一种类型转换为另一种类型。这是一个具体的例子:

Maybe.map String.fromInt (Just 42)

String.fromInt具有类型Int -> String,我们将其用作Maybe.map的第一个参数。因此,如果我们尝试将其替换为map

String.fromInt : (Int -> String)
Maybe.map      : (a   -> b     ) -> Maybe a -> Maybe b

我们看到Int替代了aString替代了b。因此,Maybe a必须为Maybe IntMaybe b必须为Maybe String。这意味着如果我们尝试给它一个Maybe String

Maybe.map String.fromInt (Just "foo")

我们将收到错误:

The 2nd argument to `map` is not what I expect:

1 | foo = Maybe.map String.fromInt (Just "foo")
                                    ^^^^^^^^^^
This `Just` call produces:

    Maybe String

But `map` needs the 2nd argument to be:

    Maybe Int
© www.soinside.com 2019 - 2024. All rights reserved.