/usr/lib/ocaml/list.ml
和其他 .ml
文件.ml
文件列表实现是一个有趣的学习对象。举个例子,map
函数可以像这样实现:
let rec map f = function
| [] -> []
| a::l -> f a :: map f l
但实现方式是这样的:
let rec map f = function
| [] -> []
| a::l -> let r = f a in r :: map f l
有什么区别?执行这个:
List.map print_int [1;2;3] ;;
map print_int [1;2;3] ;;
第一个打印出123,但是第二个打印出321!由于对于f a
的求值可能会产生副作用,强制正确的顺序非常重要。这正是官方map实现所做的。实际上,即使所有实现都遵循相同的顺序,OCaml中的参数求值顺序也是未指定的,详情请见OCaml文档。
另外,请参考Jane Street博客上关于优化List.map的文章来考虑性能问题(对于小列表,List.map
是高效的)。
Map
函数的实现在OCaml源代码分发包中的stdlib/map.ml
中。这些应该已经安装在您的系统上了。最有可能(假设是Unix系统),它们位于/usr/lib/ocaml或/usr/local/lib/ocaml中。只需打开任何.ml
文件即可。
f a :: map f li
版本的 map,在最近版本的 OCaml 中运行ignore (map print_int [1;2;3])
将会打印出 321。@jayphelps,你的测试设置可能有问题。 - gasche