简体   繁体   English

F# 中的范围混淆

[英]Scope confusion in F#

Let's consider this code:让我们考虑一下这段代码:

type TypeA = 
    {
        A : int
    }

type TypeB =
    {
        B : float
    }

module Test =
    let mutable c : TypeA = { A = 0 }

module Test2 =
    let mutable c : TypeB = { B = 0 }

it produces the error:它产生错误:

typecheck error This expression was expected to have type
    'float'    
but here has type
    'int'    

What I do not understand is why there is a collision between the two variables 'c' .我不明白的是为什么两个变量'c'之间会发生冲突。

They have different scopes:它们有不同的范围:

type TypeA = 
    {
        A : int
    }

module Test =
    let mutable c : TypeA = { A = 0 }

module Test2 =
    let mutable c : TypeA = { A = 0 }

with

Test.c <- { A = 1 }
Test2.c <- { A = 2 }
Test.c, Test2.c

gives

{ FSI_0009+TypeA: A: 1 } { FSI_0009+TypeA: A: 2 } { FSI_0009+TypeA: A: 1 } { FSI_0009+TypeA: A: 2 }

Can someone explain why there is this error?有人可以解释为什么会出现这个错误吗?

There is no collision between two variables c - they are defined in separate modules.两个变量c之间没有冲突 - 它们在不同的模块中定义。 F# just cannot implicitly convet integer literal 0 to float. F# 只是不能隐式地将整数文字0为浮点数。 Use 0.0 or 0. in the second case:在第二种情况下使用0.00.

let mutable c : TypeB = { B = 0.0 }

Also, F# type inference is smart enough to infer that the first variable c has type TypeA , and the second variable c has type TypeB (because record labels are different) so you can even remove type annotations here:此外,F# 类型推断足够智能,可以推断第一个变量c类型为TypeA ,第二个变量c类型为TypeB (因为记录标签不同),因此您甚至可以在此处删除类型注释:

module Test =
    let mutable c = { A = 0 } // TypeA inferred

module Test2 =
    let mutable c = { B = 0. } // TypeB inferred

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM