如何在绑定中添加类型注释 [英] How to add type annotation in let binding

查看:109
本文介绍了如何在绑定中添加类型注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是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 而不是新的多态< 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆