gpt4 book ai didi

types - 输入模块 Printf

转载 作者:行者123 更新时间:2023-12-05 00:27:28 25 4
gpt4 key购买 nike

Module Printf 的文档中, 看不懂('a, out_channel, unit) format 的机制,以为我在实践中经常使用它。

例如,以下函数在编译时类型良好:

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匹配 "From %a To %a" print co0 print co1 .

此外, print 的签名是 out_channel -> t -> unit , 为什么是 print co0 print co1在代码中可以接受吗?

一句话,谁能解释一下 Printf.fprintf Pervasives.stdout "From %a To %a" print co0 print co1是打字吗?

最佳答案

OCaml 有一个围绕格式字符串的打字技巧。这很奇怪,但对其简单且类型安全的 printf 函数很有用。

通常,字符串文字被输入为字符串:

# "(%d, %d)";;
- : string = "(%d, %d)"

但如果它们具有“格式化”类型上下文,则它们不是:
# ( "(%d, %d)" : (_,_,_) format );;
- : (int -> int -> 'a, 'b, 'a) format = <abstr>

OCaml 类型检查器将文字视为格式字符串,然后对其使用特殊的类型规则:它找到两个 %d在那里,并给出一个类型 (int -> int -> 'a, 'b, 'a) format这意味着它是一个格式字符串,可以接受 2 个整数并做一些事情。

将字符串文字与 Printf 函数一起使用会给出相同的“格式”键入上下文,因此“(%d, %d)”不是单纯的字符串,而是这种格式类型:
# Printf.fprintf stdout "(%d, %d)";;
- : int -> int -> unit = <fun>
(t1, t2, t3) format大致有以下含义:
  • t1 表示格式字符串如何作为函数运行:“%d”对于此 t1 部分中的某些类型 t 应该具有“int -> t”,因为它需要一个整数并执行某些操作(主要是打印)。
  • t2 是 channel 的类型
  • t3 是给定所有格式参数时的最终结果类型。

  • 您可以按如下方式进行验证:
    # (fun x -> Printf.fprintf stdout x, x) "(%d, %d)";;
    - : (int -> int -> unit) * (int -> int -> unit, out_channel, unit) format =
    (<fun>, <abstr>)
    "(%d, %d)"此处用于获取 2 个整数参数,用于将字符串发送到类型为 out_channel 的标准输出。 , 然后最后返回 unit .

    其实 format type 只是 format6 的别名有 6 个类型参数,这 3 个类型参数用于其他格式字符串输入技巧。但我们不会从这里走得更远。

    所以现在为“%a”。
    # ( "%a" : (_, out_channel, unit) format);;
    - : ((out_channel -> 'a -> unit) -> 'a -> unit, out_channel, unit) format = <abstr>

    这告诉你 Printf.fprintf stdout "%a"接受两个参数。一个是 out_channel -> 'a -> unit 类型的函数另一个是 'a .

    如果你看到这种类型,那么很容易看到 Printf.fprintf stdout "%a" print co0是很好的类型。请注意,它不是 Printf.fprintf stdout "%a" (print co0) (这是我多年前第一次看到 "%a" 时误读的内容。)
    Printf.fprintf stdout "%a" print co0尝试打印 co0使用打印机 print .这个分版的 channel 当然是 stdoutPrintf.fprintf .

    关于types - 输入模块 Printf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20606901/

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