gpt4 book ai didi

f# - 为什么用 obj 进行柯里化(Currying)不起作用?

转载 作者:行者123 更新时间:2023-12-04 04:45:14 25 4
gpt4 key购买 nike

你能解释为什么一个有效而另一个无效吗?

给定

//fu : unit -> unit
let fu() = ();;

这个作品
//exec : (unit -> unit) -> int -> unit
let exec (f:(unit -> unit)) (data:int) = f();;

//this works, and p : int -> unit
let p = exec fu;;

它适用于其他类型的 datastring , long , ETC。

这不起作用
//exec : (unit -> unit) -> obj -> unit
let exec (f:(unit -> unit)) (data:obj) = f();;

let p = exec fu;;

我收到以下错误:

error FS0030: Value restriction. The value 'p' has been inferred to have generic type val p : ('_a -> unit)
Either make the arguments to 'p' explicit or, if you do not intend for it to be generic, add a type annotation.



请注意,这些情况之间的唯一区别是 data 的类型。范围。
什么时候是 objSystem.Object'a - 它不起作用。

另一件事是,如果 data有类型 obj然后发生以下情况:
//Data type is obj
let exec (f:(unit -> unit)) (data:obj) = f();;

//specifying parameters explicitly
let p x = exec fu x;;

现在 p签名为 'a -> unit ,而不是 obj -> unit .

所以问题是:为什么当 data 时“快捷”currying 不起作用?是 obj'a以及为什么 p 的类型是 'a -> unitdataobj ?

最佳答案

所以我认为问题在于 F# 似乎在错误的点上进行了概括(从你的角度来看):

这是您的代码的一个版本,乍一看不应该进行类型检查:

let exec (f:unit -> unit)  (data:obj) = f();;
let p:int -> unit = exec (fun () -> ());;

这看起来很奇怪 int <> obj .

此外,这是一个更简单的示例,它显示了您的行为(来自经过修改的规范)
type Base() =
member b.X = 1
type Derived(i : int) =
inherit Base()
member d.Y = i
let exec (f:unit -> unit) (data:Base) = f();;
let p = exec (fun () -> ());;

这会产生值限制错误。

这更清楚地表明,由于 F# 在函数调用之前插入了隐式向上转换,因此代码在它是函数的情况下是有效的,但是一旦将其设为显式值,就不能使用这种转换。

如果你想让你的代码编译,你需要通过添加一个类型注释来移动 upcast 的位置:
let exec (f:unit -> unit)  (data:obj) = f()
let p:obj -> unit = exec (fun () -> ());;

关于f# - 为什么用 obj 进行柯里化(Currying)不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18298135/

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