gpt4 book ai didi

f# - 为什么模块与类中相同 F# 函数的类型签名之间存在差异?

转载 作者:行者123 更新时间:2023-12-01 06:07:05 25 4
gpt4 key购买 nike

my question here密切相关,但实际上是一个不同的问题......

考虑以下 F#:-

type TestClass() =
let getValFromMap m k = Map.find k m
let mutable someMap : Map<string,int> = Map.empty
let getValFromMapPartial key = getValFromMap someMap key
let getValFromMapPartialAndTacit = getValFromMap someMap

module TestModule =
let getValFromMap m k = Map.find k m
let mutable someMap : Map<string,int> = Map.empty
let getValFromMapPartial key = getValFromMap someMap key
let getValFromMapPartialAndTacit = getValFromMap someMap

在类案例和模块案例中,getValFromMapPartialgetValFromMapPartialAndTacit 的行为方式截然不同,并且编译为 IL 的方式也不同。在类和模块的情况下,前者表现得像一个真正的语法函数,而后者表现得像一个 lambda 计算函数(我知道这一点要感谢用户 Marc Sigrist)。

在模块的情况下,类型签名似乎是正确的:-

getValFromMapPartial : key:string -> int
getValFromMapPartialAndTacit : (string -> int)

但在 class 的情况下,类型签名是相同的:-

getValFromMapPartial : (string -> int)
getValFromMapPartialAndTacit : (string -> int)

为什么会这样?

既然 getValFromMapPartial 在这两种情况下都充当了真正的句法函数,为什么在类情况下将其键入为 lambda 计算函数?

最佳答案

我只能想到几次你需要担心 A -> B 之间的区别和 (A -> B) (有关相关评论,请参阅 F# 规范关于签名一致性的部分):

  • 当你想实现一个模块签名时,只有句法函数可以作为带有签名A -> B的东西的实现。 ,而句法函数或任何其他函数值都可以实现签名 (A -> B) .也就是说,后一个签名是前者的超集。
  • 当您关心您的代码在其他 .NET 语言中的显示方式时,带有签名的函数 A -> B作为方法实现,而带有签名的函数 (A -> B)被实现为类型 Microsoft.FSharp.Core.FSharpFunc<A,B> 的值.

否则,差异无关紧要。在这种情况下,正如@ildjarn 指出的那样,类型定义中的 let-bound 值是私有(private)的,因此上述两个注意事项不会对 TestClass 起作用。它只是一个无关紧要的实现细节。

关于f# - 为什么模块与类中相同 F# 函数的类型签名之间存在差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27047420/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com