我想使用具有类型签名的函数向我的项目添加调试打印:
bool -> Printf.TextWriterFormat<'a> -> 'a
Run Code Online (Sandbox Code Playgroud)
即它应该采取一个bool来表明我们是否处于详细模式,并使用它来决定是否打印.
例如,让我们说dprint : bool -> Printf.TextWriterFormat<'a> -> 'a我希望这种行为:
> dprint true "Hello I'm %d" 52;;
Hello I'm 52
val it : unit = ()
> dprint false "Hello I'm %d" 52;;
val it : unit = ()
Run Code Online (Sandbox Code Playgroud)
我们的想法是可以使用命令行标志来避免控制此输出.我还想避免"非冗长"情况下的运行时成本.可以使用以下方法定义一个这样工作的函数kprintf:
let dprint (v: bool) (fmt: Printf.StringFormat<'a,unit>) =
let printVerbose (s: string) =
if v then System.Console.WriteLine(s)
fmt |> Printf.kprintf printVerbose
Run Code Online (Sandbox Code Playgroud)
但打印/忽略一系列数字List.iter (dprint b "%A") [1..10000](b\in {true,false})对我机器上的两个b值都需要1.5s.
我想出了另一种使用反射的方法,该方法构建了一个适当类型的函数来丢弃格式化参数:
let dprint (v: …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用FParsec解析标准的简单类型(在lambda演算的意义上),但是我很难从Lex/Yacc样式转到FParsec中使用的样式,特别是在递归定义方面.
我试图解析的类型示例如下:
这是我的尝试:
type SType =
| Atom
| Arrow of SType * SType
let ws = spaces
let stype, styperef = createParserForwardedToRef()
let atom = pchar 'o' .>> ws |>> (fun _ -> Atom)
let arrow = pipe2 (stype .>> (pstring "->" .>> ws))
stype
(fun t1 t2 -> Arrow (t1,t2))
let arr = parse {
let! t1 = stype
do! ws
let! …Run Code Online (Sandbox Code Playgroud) 在我的emacs包fsharp-mode的持续集成测试中,我在测试中添加了字节编译,以便立即得到反馈.我大致使用:
emasc -batch batch-byte-compile *.el
Run Code Online (Sandbox Code Playgroud)
如果有错误,则返回非零值,但如果只是一个警告,则返回非零值.如果有任何警告,我也会收到警告,因为这可能包括调用未定义的函数(由于错字而发生过).
那么:如果编译警告,我如何获得非零返回码?
我正在尝试使用需要睡眠的ert来设置一些测试,以便后台进程继续进行.我尝试过使用sleep-for和accept-process-output.两者都不可靠.这是一个小例子.
此测试只是休眠5秒钟,然后检查至少3秒钟.使用sleep-for它立即完成并失败.如果shell-command取消注释,则需要5秒才能成功!这里发生了什么?
(ert-deftest timetest ()
(let ((now (cadr (current-time))))
;(shell-command "sleep 5")
(sleep-for 5)
(should (< now (- (cadr (current-time)) 3)))))
Run Code Online (Sandbox Code Playgroud)
编辑:
当我测试前面的例子时,我的环境肯定有些奇怪.这个稍微改变的示例包含一个像我需要测试的后台进程,但失败了.我以交互方式测试它并使用命令:
emacs --batch -l example.el -f ert-run-tests-batch-and-exit
Run Code Online (Sandbox Code Playgroud)
(ert-deftest timetest ()
(let ((now (cadr (current-time))))
(start-process "echo" "*echo*" "echo" "hello world")
(sleep-for 5)
(should (< now (- (cadr (current-time)) 3)))))
Run Code Online (Sandbox Code Playgroud)
输出是:
Test timetest condition:
(ert-test-failed
((should
(< now
(- ... 3)))
:form
(< 55177 55174)
:value nil))
FAILED 1/1 timetest
Ran …Run Code Online (Sandbox Code Playgroud)