前面的答案很好,但写和读有点无聊,而且因为它使用自然数,所以非常有限。为什么不直接转向整数?
首先将每个 ascii 字符映射到一个整数:
Require Import ZArith String Ascii.
Open Scope Z_scope.
Definition Z_of_bool (b : bool) := if b then 1 else 0.
(* This coercion is used to make the next function shorter to write and read *)
Coercion Z_of_bool : bool >-> Z.
Definition Z_of_ascii a :=
match a with
Ascii b1 b2 b3 b4 b5 b6 b7 b8 =>
b1 + 2 * (b2 + 2 * (b3 + 2 * (b4 + 2 *
(b5 + 2 * (b6 + 2 * (b7 + 2 * b8))))))
end.
只需要完成一种情况,并且数字按照您获得的顺序一个接一个地整齐地放置(ascii 代码就是这样设计的,早在 Coq 发明之前)。
Definition Z_of_0 := Eval compute in Z_of_ascii "0".
Definition Z_of_digit a :=
let v := Z_of_ascii a - Z_of_0 in
match v ?= 0 with
Lt => None | Eq => Some v |
Gt => match v ?= 10 with Lt => Some v | _ => None end
end.
这是在不反转列表的情况下处理具有多个数字的字符串的另一种尝试。
Fixpoint num_prefix_and_length (s : string) : option (Z * Z) :=
match s with
EmptyString => None
| String a s' =>
match Z_of_digit a with
None => None
| Some va =>
match num_prefix_and_length s' with
None => Some (va, 1)
| Some (vs, n) => Some (va * 10 ^ n + vs, n+1)
end
end
end.
在这种情况下,该函数接受具有任何尾随字符的字符串。
Compute num_prefix_and_length "31415926 remind me of Pi".
返回一些 (31415926, 8)。