OCaml 中的 eta 扩展是否万无一失?
Is eta-expansion foolproof in OCaml?
在 OCaml 中最好始终将 eta-expand 作为万无一失的经验法则吗?
type 'x recordx = { x : int }
type 'y recordy = { y : int }
let rec ok : type n a. n recordx -> a recordy -> int =
fun algebrah x -> ok algebrah x
let rec ok : type a. a recordy -> int =
fun x ->
let go : type b. b recordy -> int = ok in
go x
let rec ok : type n a. n recordx -> a recordy -> int =
fun x y ->
let go : type b. b recordy -> int = fun y -> ok x y in
go y
let rec ok : type n a. n recordx -> a recordy -> int =
fun x y ->
let go = ok x in
go y
(* This definition has type
'b recordy -> int which is less general than
'b0. 'b0 recordy -> int
*)
let rec ko : type n a. n recordx -> a recordy -> int =
fun x y ->
let go : type b. b recordy -> int = ko x in
go y
放宽的值限制将 eta 扩展形式 fun y -> f x y
分类为可以通过 let 绑定泛化的值,与非值 f y
相反。参见 https://ocaml.org/manual/polymorphism.html#s%3Aweak-polymorphism。
此外,在像 OCaml 这样的急切语言中,eta 扩展确实改变了函数的语义。考虑
let print x =
Format.printf "x=%s@." x;
fun y -> Format.printf "y=%s@."
和
let print1 = print "x"
let print2 y = print "x" y
因此,eta-expansion 是一种语义变化转换,而不是“万无一失”的转换。
在 OCaml 中最好始终将 eta-expand 作为万无一失的经验法则吗?
type 'x recordx = { x : int }
type 'y recordy = { y : int }
let rec ok : type n a. n recordx -> a recordy -> int =
fun algebrah x -> ok algebrah x
let rec ok : type a. a recordy -> int =
fun x ->
let go : type b. b recordy -> int = ok in
go x
let rec ok : type n a. n recordx -> a recordy -> int =
fun x y ->
let go : type b. b recordy -> int = fun y -> ok x y in
go y
let rec ok : type n a. n recordx -> a recordy -> int =
fun x y ->
let go = ok x in
go y
(* This definition has type
'b recordy -> int which is less general than
'b0. 'b0 recordy -> int
*)
let rec ko : type n a. n recordx -> a recordy -> int =
fun x y ->
let go : type b. b recordy -> int = ko x in
go y
放宽的值限制将 eta 扩展形式 fun y -> f x y
分类为可以通过 let 绑定泛化的值,与非值 f y
相反。参见 https://ocaml.org/manual/polymorphism.html#s%3Aweak-polymorphism。
此外,在像 OCaml 这样的急切语言中,eta 扩展确实改变了函数的语义。考虑
let print x =
Format.printf "x=%s@." x;
fun y -> Format.printf "y=%s@."
和
let print1 = print "x"
let print2 y = print "x" y
因此,eta-expansion 是一种语义变化转换,而不是“万无一失”的转换。