理解类型注解中的类型变量
Understanding type variables in type annotations
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
那么,当类型必须是同一类型时,为什么它们被注释为 a
和 b
?
我希望 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
确实对输入参数类型和 return 类型使用了相同的类型变量,那么它们会使用相同的类型变量,但是 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 Int
而 Maybe 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
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
那么,当类型必须是同一类型时,为什么它们被注释为 a
和 b
?
我希望 a
跟踪类型,即:
map : (a -> a) -> Maybe a -> Maybe a
So why are the types annotated as
a
andb
when they must be the same type?
他们没有!如果 map
确实对输入参数类型和 return 类型使用了相同的类型变量,那么它们会使用相同的类型变量,但是 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 Int
而 Maybe 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