如何在绑定中添加类型注释 [英] How to add type annotation in let binding
问题描述
我是Haskell的初学者(ish),我发现错误信息很难理解(我想它是随时间而来的)。无论如何,为了帮助我理解我的错误,我尝试在let绑定中添加带有类型注释的中间变量,并发现它会产生更多错误,即使我的类型是(我认为)是正确的。
示例;
f :: a - > a
fx =
让x'= x :: a
in x'
生成以下错误:
test.hs:3:12:
无法匹配预期类型实际类型为'a'的'a2'
'a2'是一个由
绑定的刚性类型变量表达式类型签名:a2 at test.hs:3:12
`a'是由
绑定的刚性类型变量f :: a - >的类型签名。 a at test.hs:1:6
在表达式中:x :: a
在x'的等式中:x'= x :: a
在表达式中:let x' = x :: a in x
我做错了什么或者做不到? 您需要
{ - #LANGUAGE ScopedTypeVariables# - } $ scopedTypeVariables
b
$ bf :: forall a。 a - > a
fx =
让x'= x :: a
in x'
说明
如果您有类似这样的签名
f :: a - > a
则表明 f
是多态的并适用于任何 a
的选择。因此, f
可以是
,用于类型 Int - > Int
或类型 Bool - > Bool
,或者在类型 [Int - > Bool] - > [Int - >布尔]
–无论你喜欢什么。
如果你有这样的类型注释
x :: a
它意味着类似的东西,即 x
应该可以在您选择的任何类型中使用。但你的情况并非如此。外部函数 f
是多态的,但在函数中, x
必须是 输入用户为外部 x
选择的 a
。默认情况下,Haskell在不同类型签名和注释中发生的类型变量之间没有连接。但是,您可以通过启用 ScopedTypeVariables
扩展名来告诉它。现在,通过前缀 a - >一个
与 forall a。
,您可以明确指示Haskell使 a
成为可见在 f
的定义中指定特定的类型变量。如果您然后注释 x :: a
,它会引用外部 a
而不是新的多态<
I'm a beginner(ish) in Haskell and I find error message really hard to understand (I guess it comes with time). Anyway, to help me understanding my mistakes, I tried to add intermediate variable with type annotation in a let binding and found that it generate even more errors, even though my type are (I think) correct.
Example;
f :: a -> a
f x =
let x' = x :: a
in x'
Generate the following error
test.hs:3:12:
Couldn't match expected type `a2' with actual type `a'
`a2' is a rigid type variable bound by
an expression type signature: a2 at test.hs:3:12
`a' is a rigid type variable bound by
the type signature for f :: a -> a at test.hs:1:6
In the expression: x :: a
In an equation for x': x' = x :: a
In the expression: let x' = x :: a in x
Am I doing something wrong or is it not possible to do so ?
Solution
You need the ScopedTypeVariables
extension for this to work, like this:
{-# LANGUAGE ScopedTypeVariables #-}
f :: forall a. a -> a
f x =
let x' = x :: a
in x'
Explanation
If you have a type signature like this
f :: a -> a
then it indicates that f
is polymorphic and works for any choice of a
. So f
could be
used at type Int -> Int
, or at type Bool -> Bool
, or at type [Int -> Bool] -> [Int -> Bool]
– whatever you like.
If you have a type annotation like this
x :: a
it means a similar thing, namely that x
should be usable at any type of your choice. But that's not true in your case. The outer function f
is polymorphic, but within the function, x
has to be of the same type a
that the user has chosen for the outer x
. By default, Haskell makes no connection between type variables occurring in different type signatures and annotations. However, you can tell it to do so by enabling the ScopedTypeVariables
extension. Now, by prefixing a -> a
with forall a.
, you can explicitly instruct Haskell to make a
visible as a specific type variable within the definition of f
. If you then annotate x :: a
, it refers to the outer a
rather than a new polymorphic a
.
这篇关于如何在绑定中添加类型注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!