2011-09-26 22 views
5

Soy un novato OCaml. Estoy intentando descubrir cómo manejar un operador de comparación que pasó a una función.OCaml: Usar un operador de comparación pasado a una función

Mi función solo intenta pasar en un operador de comparación (=, <,>, etc.) y un int.

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

Tenía la esperanza de que este código se evaluaría a (si es un "=" se pasaron en):

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

Sin embargo, esto no está funcionando. En particular, se cree que x es un bool, como lo demuestra este mensaje de error:

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

¿Cómo puedo hacer lo que yo estoy tratando de hacer?

En una pregunta secundaria, ¿cómo podría haber descubierto esto por mi cuenta así que no tengo que depender de la ayuda externa de un foro? ¿Qué buenos recursos hay disponibles?

+0

También tenga en cuenta que una vez que lo tienes en una variable, no puede utilizarlos como operadores en línea. –

Respuesta

10

Los operadores de comparación como < y = son secretamente funciones de dos parámetros (binarias). Para pasarlos como un parámetro, usa la notación (<). Para utilizar este parámetro dentro de su función, simplemente tiene que tratar como nombre de función:

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

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

Para crear funciones de infijo hay algunas limitaciones que se describen aquí, http://stackoverflow.com/questions/6150551/ocaml-why-i-cant-use-this-operator-infix – nlucaroni

+0

Aceptado para dar la más simple y precisa solución. –

4

OCaml le permite tratar operadores infijos como identificadores encerrándolas entre paréntesis. Esto funciona no solo para los operadores existentes sino también para los nuevos que quiera definir. Pueden aparecer como nombres de funciones o incluso como parámetros. Deben consistir en caracteres de símbolos y se les da la prioridad asociada con su primer personaje. Así que si realmente quisiera, podría utilizar la notación infija para el parámetro de comparación de 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 
# 

(No está claro que esto hace myFunction más fácil de leer Creo definición de nuevos operadores infijos debe hacerse con moderación..)

Para responder a su pregunta lado, una gran cantidad de recursos OCaml se encuentran en esta otra página StackOverflow:

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

2

varias posibilidades:

uso de una nueva definición para redefinir el operador de comparación:

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

También podría pasar el @ directamente sin la definición adicional.

Como otra solución que pueden utilizar algunas funciones de ayuda a definir lo que necesita:

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

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

Otra nota: La función auxiliar que definí para esto ya está disponible si usa Baterías como |> y <| en el módulo BatStd. En general, las baterías a menudo simplifican su vida para tales tareas. – LiKao

Cuestiones relacionadas