2011-09-26 30 views
5

我是OCaml noob。我想弄清楚如何处理传入函数的比较运算符。OCaml:使用传入函数的比较运算符

我的函数只是试图传入一个比较运算符(=,<,>等)和一个int。

let myFunction comparison x = 
if (x (comparison) 10) then 
    10 
else 
    x;; 

我希望这个代码将评估为(如果 “=” 获得通过的):

if (x = 10) then 
    10 
else 
    x;; 

但是,这是行不通的。特别是,它认为x是一个布尔值,如此错误消息所证明的那样:

This expression has type 'a -> int -> bool 
but an expression was expected of type int 

我该如何做我想做的事?

关于一个侧面的问题,我怎么能自己想出来的,所以我不必依靠外部的论坛帮助?有什么好的资源可用?

+0

另外请注意,一旦你在一个变量拥有它,你不能把它们作为内嵌运营商。 –

回答

10

比较运算符如<=是秘密的双参数(二进制)函数。要将它们作为参数传递,请使用(<)表示法。要使用该参数的函数中,你只是把它当作函数名称:

let myFunction comp x = 
    if comp x 10 then 
    10 
    else 
    x;; 

printf "%d" (myFunction (<) 5);; (* prints 10 *) 
+0

对于创建infix函数,这里列出了一些限制,http://stackoverflow.com/questions/6150551/ocaml-why-i-cant-use-this-operator-infix – nlucaroni

+0

接受为给予最简单,准确解。 –

4

OCaml中,您可以通过在括号括起来治疗缀运营商标识符。这不仅适用于现有的运营商,还适用于您想要定义的新运营商。它们可以显示为函数名称或甚至作为参数。它们必须由符号字符组成,并赋予与其第一个字符相关的优先权。所以,如果你真的想,你可以使用中缀表示法的myFunction比较参数:

 Objective Caml version 3.12.0 
# let myFunction (@) x = 
     x @ 10;; 
val myFunction : ('a -> int -> 'b) -> 'a -> 'b = <fun> 
# myFunction (<) 5;; 
- : bool = true 
# myFunction (<) 11;; 
- : bool = false 
# myFunction (=) 10;; 
- : bool = true 
# myFunction (+) 14;; 
- : int = 24 
# 

(目前还不清楚这使得myFunction任何更容易阅读,我认为新的中缀运算符的定义,应该尽量少做。 )

要回答你的身边的问题,很多OCaml的资源都列在这个StackOverflow的其他页面上:

https://stackoverflow.com/questions/2073436/ocaml-resources

2

几种可能性:

使用了新的定义重新定义比较操作:

let myFunction comparison x = 
    let (@) x y = comparison x y in 
    if (x @ 10) then 
    10 
    else 
    x;; 

你也可以直接通过@没有额外的定义。

作为另一种解决方案可以使用一些辅助函数来定义你所需要的:

let (/*) x f = f x 
let (*/) f x = f x 

let myFunction comparison x = 
    if x /* comparison */ 10 then 
    10 
    else 
    x 
+0

另一个说明:如果您使用电池作为|>和<|电池,则我为此定义的帮助程序功能已可用。在BatStd模块中。总而言之,电池往往会让你的生活更容易完成这些任务。 – LiKao