我想定义一个函数check_char_fun:(char - >'a) - > (char - >'a) - > bool,给出了两个功能 在char上,当两个函数相同时返回true(即,当它们对char的每个可能值完全相同时),否则返回false。
let check_char_fun f1 f2 =
let aux = true
for i=0 to 255 do
if (f1 (char_of_int i))=(f2 (char_of_int i))
then aux=false;
done;
if aux=true
then true
else false;;
我正在学习OCaml,所以我不知道该怎么做。
答案 0 :(得分:2)
首先,您必须定义“行为”是什么。如果您的函数可以引发异常,则问题会变得更加困难。您的代码假设函数始终返回一个值,这似乎是对开始问题的一个很好的简化。
你也在使用OCaml使用的(稍微过时的)字符定义,因为代码限制在0 .. 255范围内。这也似乎没问题。
因此,我在您的代码中看到的唯一问题是您希望能够更改aux
变量的值。 OCaml中的变量是不可变的:你不能改变它们绑定的值。
如果您希望保持代码大部分不变,可以更改aux
,使其值为引用到bool。然后你可以改变 in 引用的布尔值(aux
仍然绑定到同一个引用)。
要引用bool并更改值:
# let x = ref true;;
val x : bool ref = {contents = true}
# !x;;
- : bool = true
# x := false;;
- : unit = ()
# !x;;
- : bool = false
(研究OCaml的原因之一是学习如何使用不可变值。所以我建议寻找其他方法来解决不需要使用引用的问题。)
答案 1 :(得分:2)
你几乎在那里:
let check_char_fun f1 f2 =
let aux = ref true in
for i = 0 to 255 do
if (f1 (char_of_int i)) = (f2 (char_of_int i)) then aux := false
else ()
done;
!aux
与命令式语言中的变量不同,OCaml中的 bindings 默认情况下是不可变的。要创建实变量,我们创建一个可变的bool ref
,可以在循环中进行更改。
OCaml在命令式语言之类的语句和表达式之间没有区别:只有表达式!这就是为什么你总是需要else
条款到if
;这种方式生成的表达式总是返回一个值(在if
和else
情况下),其类型必须相同 - 在这种情况下类型为unit
(类型为值()
- 在C中为void
。
你的代码不像OCaml那样,但这就是我个人对OCaml的喜爱:功能风格并没有被强行扼杀,你可以在不进入学术象牙塔的情况下以强制性的方式实现算法。
答案 2 :(得分:1)
以下将每个函数应用于0 .. 255范围内的每个字符值并比较它们的结果,但它不检查函数引发异常或在其他地方引起副作用的情况:
open Core.Std
let check_char_fun f1 f2 =
let chars = List.map ~f:char_of_int (List.range 0 256) in
List.for_all ~f:(fun c -> (f1 c) = (f2 c)) chars
答案 3 :(得分:1)
let rec range i j =
if i > j then [] else i :: (range (i+1) j);;
let check_char_fun f1 f2 =
let lc = List.map char_of_int (range 0 255) in
List.for_all (fun c -> (f1 c) = (f2 c)) lc;;
测试:
#let id x =x;;
val id : 'a -> 'a = <fun>
# check_char_fun id id;;
- : bool = true
# check_char_fun id (fun x -> 'a');;
- : bool = false
或者:
exception Fails_in of char;;
let check_char_fun f1 f2 =
let lc = List.map char_of_int (range 0 255) in
List.iter (fun c ->
if (f1 c) <> (f2 c) then raise (Fails_in c)
) lc;;
# try (
check_char_fun id id
) with Fails_in c -> Printf.printf "Diff(%d)(%c)" (int_of_char c) c
;;
- : unit = ()
# try (
check_char_fun id (fun x -> 'a')
) with Fails_in c -> Printf.printf "Diff(%d)(%c)" (int_of_char c) c
;;
Diff(0)()- : unit = ()