Types 在模块Printf中键入
在的文档中,我不理解Types 在模块Printf中键入,types,ocaml,Types,Ocaml,在的文档中,我不理解('a,out\u channel,unit)格式的机制,认为我在实践中经常使用它 例如,在编译时,以下函数类型正确: type t = { x: int; y: int } let print (chan: out_channel) (co: t) : unit = Printf.fprintf chan "(%d, %d)" x y let try (co0: t) (co1: t) = Printf.fprintf Pervasives.stdo
('a,out\u channel,unit)格式的机制,认为我在实践中经常使用它
例如,在编译时,以下函数类型正确:
type t =
{ x: int;
y: int }
let print (chan: out_channel) (co: t) : unit =
Printf.fprintf chan "(%d, %d)" x y
let try (co0: t) (co1: t) =
Printf.fprintf Pervasives.stdout "From %a To %a" print co0 print co1
Printf.fprintf
的签名是:out_channel->('a,out_channel,unit)format->'a
,但我看不到('a,out_channel,unit)format
在“从%a到%a”print co0 print co1中匹配什么
另外,print
的签名是out\u channel->t->unit
,为什么代码中可以接受print co0 print co1
一句话,谁能解释一下从%a到%a的“print co0 print co1
是如何键入的?OCaml对格式字符串有一种键入技巧。这很奇怪,但由于其简单且类型安全的printf函数很有用
通常,字符串文字类型为字符串:
# "(%d, %d)";;
- : string = "(%d, %d)"
但如果它们具有“格式化”类型的上下文,则不是:
# ( "(%d, %d)" : (_,_,_) format );;
- : (int -> int -> 'a, 'b, 'a) format = <abstr>
(t1、t2、t3)格式大致有以下含义:
- t1表示格式字符串作为函数的行为方式:“%d”应该在t1部分的某些类型t中具有“int->t”,因为它接受整数并执行某些操作(主要是打印)
- t2是通道的类型
- t3是给定所有格式参数时的最终结果类型
您可以按如下方式进行验证:
# (fun x -> Printf.fprintf stdout x, x) "(%d, %d)";;
- : (int -> int -> unit) * (int -> int -> unit, out_channel, unit) format =
(<fun>, <abstr>)
这说明Printf.fprintf标准输出“%a”
接受两个参数。一个是out\u channel->'a->unit
类型的函数,另一个是'a
如果您看到此类型,则很容易看到Printf.fprintf stdout“%a”print co0
类型正确。请注意,它不是Printf.fprintf标准输出“%a”(print co0)
(这是我多年前第一次看到“%a”
时读错的。)
Printf.fprintf标准输出“%a”print co0
尝试使用打印机print
打印co0
。这个子打印的通道当然是stdout
,它被提供给Printf.fprintf
我将描述我的直觉,知道事情是如何运作的人可以纠正我或提供更好的答案('a,out\u channel,unit)格式
是为格式字符串提供的类型。格式字符串不被解析为字符串,即它没有类型string
。相反,例如“从%a到%a”
被解析为具有类型(((('a->'b->'c)->'b->('a->'d->'c)->'d->'c),'a,'c)格式。当你将其与('a,out\u channel,unit)格式统一时,你得到(((out\u channel->'b->'unit)->'b->(out\u channel->'d->unit)->'d->'d->unit),out\u channel,unit)格式。因此,Printf.fprintf-pervisives.stdout“从%a到%a”
的类型是(out\u channel->'b->unit)->'b->(out\u channel->'d->'d->unit)->'d->unit
# (fun x -> Printf.fprintf stdout x, x) "(%d, %d)";;
- : (int -> int -> unit) * (int -> int -> unit, out_channel, unit) format =
(<fun>, <abstr>)
# ( "%a" : (_, out_channel, unit) format);;
- : ((out_channel -> 'a -> unit) -> 'a -> unit, out_channel, unit) format = <abstr>