Stdio.printf 给出类型错误,而 Printf.printf 则没有

问题描述 投票:0回答:1

一个“小”ocaml printf 问题。 Printf 模块中有一个 printf 可以在 utop 甚至 ocaml (解释器)和 ocamlc (编译器)中工作 Stdio模块中有printf。仅适用于 utop 和 ocaml(解释器),但不适用于编译代码。

当我用以下代码编译代码时:

camlopt -I 
ocamlfind query stdio
 -o penelem penelem.ml
Printf.printf 版本工作正常,但 Stdio.printf 版本失败并显示:

Error: This expression has type string but an expression was expected of type ('a -> 'b, Stdio.Out_channel.t, Base.unit) Base.format Base.format is abstract because no corresponding cmi file was found in path. 

据称 Printf.printf 在某些时候已被弃用,取而代之的是 Stdio.printf(根据编译器消息)。所以我假设他们最终试图将每个人都转移到 Stdio.printf 上。 如果有人广泛使用 Stdio.printf,我一直在思考复杂的类型错误,但仍然对该函数的确切语句构造感到困惑。进一步的例子将不胜感激。为什么 Stdio.printf 文档中没有任何好的内容?看例子比认真思考更容易!

这是来自 ocaml 入门课程的简单代码:

open Stdio
(* open Printf *)

let rec sum lst = 
  match lst with 
  | [] -> 0
  | h :: t -> h + sum t ;;


let numbers = [2; 8; 4; 5; 9] ;;

let result = sum numbers ;; 

let () = Stdio.printf "About to print some numbers ...\n" ;;

let () = Stdio.printf  "Sum =  %d\n%!" result  ;;

 let name = "Alice" in printf "Hello, %s\n%!" name


let rec print_list lst = 
  match lst with
  | [] -> printf "\n" ;
  | head :: tail -> 
      printf "%d " head ; 
      print_list tail ;;


let () = print_list numbers ;;

在Stdio.printf和Printf.printf之间来回切换 在每个语句后放置一个双分号以隔离它们。

从 Stdio.printf 和 Printf.print 中,我期望解释和编译的代码具有相同的输出。 该异常是预期的并且是示例的一部分。

#use "penelem.ml" ;;
val numbers : int/2 list/2 = [1; 8; 2; 5]
val words : string/2 list/2 = ["ocean"; "water"; "sea"]
val before_last : 'a list/2 -> 'a = <fun>
penultimate element of numbers is: 2
penultimate element of words is: water
Penultimate element of [1,2] is 1
Exception: (Failure "Singleton List -> No Penultimate Element").
Raised at Stdlib.failwith in file "stdlib.ml", line 29, characters 17-33
Called from penum in file "penelem.ml", line 35, characters 12-27
Called from Topeval.load_lambda in file "toplevel/byte/topeval.ml", line 89, characters 4-14

当然,Stdio.printf 给出了类型错误消息,而不是预期的输出。

ocaml ocaml-core
1个回答
0
投票

首先,标准库中的

Printf
模块根本没有被弃用。您所提到的消息可能只是对
base
有意见的
Printf
替代标准库。

其次,示例中的类型错误是由于误用

ocamlopt
造成的:直接调用
-I ...
时,所有传递依赖项都必须包含在
ocamlopt
中,如类型错误消息的最后部分所述


       Base.format is abstract because no corresponding cmi file was found in path.

第三,如果您对为 OCaml 编写构建系统不感兴趣,我建议您使用

dune
(或至少
ocamlfind ocamlopt -package
)来编译您的程序。

© www.soinside.com 2019 - 2024. All rights reserved.