OCaml测试字符串是否几乎为空或包含关键字



我在OCaml中遇到了一个问题,我目前正在学习,但我还是个新手。如果字符串为空或仅包含空白,我想创建一个返回true的函数,同时删除任何出现的beginend

我已经试过了:

let isEmptyString s =  
let rec empty i =
if i < 0 then true
else
let c = String.get s i in
if c = ' ' || c = '09' then empty (pred i)
else false
in
s = Str.global_replace( Str.regexp "begin") "" s;
s = Str.global_replace( Str.regexp "end") "" s;
empty (pred (String.length s))

但很明显,这个函数并没有像我希望的那样工作,因为在调用它之后,我在Formula.importNrAgentsFormula中仍然获得了begin…以下是我的调用方法:

while true do
let input = read_line () in
if not (isEmptyString input) then
let (nr, f) = Formula.importNrAgentsFormula input in
incr counter;
flush stdout;
match choice with
| "graph" -> printRes (Graph.isSat ~verbose:verb nr f)
| _ -> printUsage ()
else ()
done

如果在OCaml方面有更多经验的人能够发现并向我解释这个错误,我会很高兴:)

提前感谢

谨致问候。

我建议让函数isEmptyString(isBlankString?)做它应该做的事情(只需检查它是否只包含空格),它不应该修改原始字符串。你可以在你的循环中做到这一点:

while true do
let input = read_line () in
let input = Str.global_replace( Str.regexp "begin") "" input in
let input = Str.global_replace( Str.regexp "end") "" input in
if not (isEmptyString input) then
...

编辑:很抱歉编辑延迟,以下是有关您的错误的一些附加信息:

如果你在OCaml中运行你的函数,你会看到这个警告:

Warning 10: this expression should have type unit.

在CCD_ 7的线路上。这是因为OCaml中的=运算符在本例中不是赋值运算符,而是相等运算符,所以在这一行中,您只需比较两个值并返回布尔值。由于OCaml期望e1;e2中的e1返回unit,因此会收到此警告。

在OCaml中,变量的值是不可变的,因此您可以:

  • 按照@Jason的建议使用另一个变量:let t = Str.global_replace( Str.regexp "begin") "" s
  • "阴影"旧值,正如我上面建议的:let s = Str.global_replace( Str.regexp "begin") "" s
  • 使用引用(指向内存中某个位置的指针):let s = ref "before" in s := "after",然后可以使用!运算符访问引用所指向的值:!s。然而,如果你正在学习函数式编程,我建议你一开始尽量不要使用OCaml的任何命令式功能来发现这种新范式及其可能性

当我在工作时,我没有带utop,但乍一看,在你的第一个文件中,文档上写着:

val global_replace : regexp -> string -> string -> string

这意味着您不需要";",因为当函数返回单位时,它是之类的语法糖

let () = print_endline("foobar")

此外,您需要使用let语句,因为您不能只重新分配s的值。我不建议隐藏变量,因为这在函数式编程中通常是不好的做法。使用类似的东西

let t = (Str.global_replace( Str.regexp "begin") "" s)

此外,您的函数做两件不同的事情。您编写的helper递归函数返回true和false,这很好(我假设它有效)。然而,你最终使用它的目的是你所得到的回报。因此,对于第一个函数are,如果"begin"one_answers"end"已被替换,则不会真正返回字符串。因此,函数的最终输出实际上应该是一个类型为(bool,string)的元组。然后,当你调用它时,你可以匹配它(例如

let b,s = isEmptyString "foobar" in
if not b then:
rest of your code

不过,我相信你对你的职能有正确的想法。在你的第二个函数中,有没有一种方法可以让你不使用while循环和计数器?(也希望你的计数器是用引用实现的,否则你就不会有任何全局性的东西)。我建议重试调用第一个函数的地方,因为循环和计数器是命令式编程的核心,而不是函数性的(这就是OCaml如此的原因

fun

:)。如果没有,那也没关系,有时如果不使用OCaml的命令式功能,你就无法在OCaml中真正做到一些事情。如果这些建议不起作用,请告诉我。

最新更新