2011-09-11 14 views
7

¿Es posible colocar instrucciones de impresión para la depuración/prueba en bloques de código? Por ejemplo, en Java puede usar System.out.println("") en medio de métodos para verificar variables u otras cosas, pero en OCaml, ¿funcionaría un comando como print_string? ¿No devolvería un valor de tipo unidad, causando un error, en lugar de permitirle imprimirlo?OCaml Imprimir las declaraciones

+0

Ocaml es diferente de Java, no tiene una impresión en lo que desee. Por ejemplo, para imprimir una lista, debe escribirla ... porque en ocaml no tiene solo objeto. –

Respuesta

14

Estará bien si incrusta la impresión en expression sequence.

ACTUALIZACIÓN

Aquí está un ejemplo concreto, debido a que la respuesta anterior fue más bien corto y, así, responde con enlaces sólo no son buenas respuestas. Es la formulación clásica recursiva de cola de factorial (sí, aburrido, pero familiar):

# let fac n = 
    let rec f i n acc = 
    if i >= n 
    then acc 
    else (Printf.printf "%8d%8d%8d\n" i n acc; f (i+1) n ((i+1)*acc)) 
    in 
    f 0 n 1;; 
val fac : int -> int = <fun> 
# fac 5;; 
     0  5  1 
     1  5  1 
     2  5  2 
     3  5  6 
     4  5  24 
- : int = 120 

Aquí se pueden ver los efectos secundarios de la impresión, pero el resultado sigue siendo resultó ser 120 como se esperaba.

+0

Genial, muchas gracias! Esto era exactamente lo que estaba buscando. ¿Las secuencias de expresión se usan generalmente para cualquier otra cosa, o es este el principal uso de ellas? ¿Supongo que también puedes usarlo para cambiar los valores de las variables? – dxu

+0

Sí, cualquier cosa que requiera estado de actualización, como actualizar el valor de las referencias, generalmente se maneja de esta manera. Hay una discusión muy agradable y detallada de esto [aquí] (http://caml.inria.fr/pub/docs/oreilly-book/html/book-ora028.html), vea la sección "Secuencia". –

10

Dado que OCaml no es un lenguaje funcional pure, existen muchas formas de hacerlo. Esta es la forma en que escribo este tipo de código, solo para un ejemplo concreto.

let rec mylength list = 
(* DEBUG *) 
let() = Printf.printf "mylength here, null list: %b\n%!" (list = []) 
in 
(* DEBUG *) 
    match list with 
    | [] -> 0 
    | _ :: rest -> 1 + mylength rest 

Después de que funcione, puede eliminar las cosas dentro de los comentarios (* DEBUG *).

¡Tenga en cuenta el uso de%! para vaciar el buffer. Si realiza una gran cantidad de depuración con printf (como yo), es realmente útil aprender sobre esto.

+0

sería más simple escribir '(* DEBUG *) Printf.printf" mylength aquí, lista nula:% b \ n%! " (lista = []); (* DEBUG *) ' – newacct

+1

Sure; como dije, solo estoy mostrando la forma en que realmente lo escribo. Soy tímido sobre el uso de punto y coma fuera de parens debido a los muchos precedentes que me quedan por aprender. –

2

Aquí está un ejemplo simple que muestra que las secuencias de expresión como se menciona en Ray Toal's answer no necesariamente tienen paréntesis alrededor de ellas:

let get_a_string = 
    let a_string = "a string" in 
    (* The semicolon causes the return value of the statement to be discarded *) 
    Printf.printf "Debug: %s\n" a_string; 
    a_string 

let() = Printf.printf "Result: %s\n" get_a_string 

Otra forma de desprenderse de valor de retorno de una función está usando ignore:

ignore (Printf.printf "Debug info"); 
Cuestiones relacionadas