2011-09-26 9 views
5

Sono un OCOBL noob. Sto cercando di capire come gestire un operatore di confronto passato in una funzione.OCaml: utilizzo di un operatore di confronto passato in una funzione

La mia funzione tenta solo di passare in un operatore di confronto (=, <,>, ecc.) E un int.

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

Speravo che questo codice sarebbe valutato come (se un "=" sono stati passati in):

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

Tuttavia, questo non sta funzionando. In particolare, si pensa che la x è un bool, come evidenziato da questo messaggio di errore:

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

Come posso fare quello che sto cercando di fare?

In una domanda a parte, come ho potuto capirlo da solo, quindi non devo fare affidamento su un aiuto esterno da un forum? Quali buone risorse sono disponibili?

+0

Si noti inoltre che una volta che hai in una variabile, non è possibile usarli come operatori in linea. –

risposta

10

Gli operatori di confronto come < e = sono funzioni segretamente a due parametri (binarie). Per passarli come parametro, utilizzare la notazione (<). Per utilizzare tale parametro all'interno vostra funzione, basta trattarlo come nome della funzione:

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

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

Per la creazione di funzioni infissi ci sono alcune limitazioni che sono descritte qui, http://stackoverflow.com/questions/6150551/ocaml-why-i-cant-use-this-operator-infix – nlucaroni

+0

Accettato per dare il più semplice, accurato soluzione. –

4

OCaml consente di trattare operatori infissi come identificatori racchiudendoli tra parentesi. Questo funziona non solo per gli operatori esistenti ma per quelli nuovi che si desidera definire. Possono apparire come nomi di funzioni o anche come parametri. Devono essere costituiti da simboli e hanno la precedenza associata al loro primo carattere. Quindi, se si voleva davvero, si potrebbe usare la notazione infissa per il parametro di confronto di 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 
# 

(Non è chiaro questo rende myFunction più facile da leggere penso definizione di nuovi operatori infissi dovrebbe essere fatto con parsimonia..)

Per rispondere alla tua domanda lato, un sacco di risorse OCaml sono elencate in questa altra pagina StackOverflow:

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

2

Diverse possibilità:

Usa una nuova definizione per ridefinire il proprio operatore di confronto:

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

si potrebbe anche passare il @ direttamente senza la definizione extra.

Come un'altra soluzione è possibile utilizzare alcune funzioni di supporto per definire ciò che è necessario:

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

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

Un'altra nota: la funzione di aiuto che ho definito per questo è già disponibile se si usano le batterie come |> e <| nel modulo BatStd. Tutto sommato Le batterie spesso rendono la vita molto più semplice per tali compiti. – LiKao

Problemi correlati