types - 理解类型注解中的类型变量

标签 types elm parametric-polymorphism type-variables

Elm docs像这样说明类型变量:

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

...the type variable a can vary depending on how List.reverse is used. But in this case, we have an a in the argument and in the result. This means that if you give a List Int you must get a List Int as well.

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

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

那么,当类型必须是同一类型时,为什么它们被注释为 ab
我希望 a 跟踪类型,即:

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

最佳答案

So why are the types annotated as a and b when they must be the same type?

他们没有!如果 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 替换了 a 并且 String 替换了 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

关于types - 理解类型注解中的类型变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59192273/

相关文章:

elm - 什么是 elm-make : Map. !:给定的键不是 map 中的元素

java - 将类型推广到 Java 中的类型系统

scala - 在Scala中,我可以动态指定参数类型的类型参数吗?

c++ - C++ 中 dynamic_cast 的缺点是什么?

c++ - 如何指定 GetDelegateForFunctionPointer 的调用类型 System : Func?

elm - Elm 的余数运算符是什么

elm - 使用 FileReader 在 Elm 中渲染本地文件

c# - 值类型存储在 (C#) 泛型集合中的什么位置

python - Robot Framework - 查询返回的关键字类型

pointers - 为什么带有多态 Ptr 的 `peek` 在与绑定(bind)一起使用时会返回 GHC.Prim.Any?