Soy un novato OCaml. Estoy jugando con fragmentos de tipo "hello world" y me encontré con esta situación. Aquí es una sesión con el intérprete con algunos comentarios adicionales:¿Por qué no funciona este pequeño fragmento de OCaml con Printf.printf?
# let average a b =
(a +. b) /. 2.;;
val average : float -> float -> float = <fun>
# average 1. 4.;;
- : float = 2.5
# string_of_float (average 1. 4.);;
- : string = "2.5"
(* this fails...*)
# let _ = Printf.printf (string_of_float (average 1. 4.));;
Error: This expression has type string but an expression was expected of type
('a, out_channel, unit) format =
('a, out_channel, unit, unit, unit, unit) format6
(* yet this works *)
# "hello!";;
- : string = "hello!"
# let _ = Printf.printf "hello!";;
hello!- : unit =()
(* another failed attempt *)
# let s = string_of_float (average 1. 4.);;
val s : string = "2.5"
# s;;
- : string = "2.5"
# let _ = Printf.printf s;;
Error: This expression has type string but an expression was expected of type
('a, out_channel, unit) format =
('a, out_channel, unit, unit, unit, unit) format6
(* and this also works?? *)
# let _ = Printf.printf "2.5";;
2.5- : unit =()
Así que aquí es la situación. string_of_float (average 1. 4.)
devuelve una cadena, como "hello!"
hace. Cuando doy "hello!"
en Printf.printf
, funciona como se esperaba. Cuando doy string_of_float (average 1. 4.)
a Printf.printf
, falla y me dice que esperaba una cadena, pero ese otro tipo extraño. ¿Pero por qué funcionan entonces "hello!"
y "2.5"
?
¿Qué está pasando?
Eso tiene sentido para mí. ¡Gracias! – dimatura
No ser capaz de construir un 'format6' en tiempo de ejecución es realmente ... deficiente. ¿Hay alguna manera (a parte de reescribirlo yo mismo) para lograr ese mismo objetivo? (Por ejemplo, ¿cómo rellenas una cadena con un número arbitrario de espacios en tiempo de ejecución? En C podemos 'sprintf (sprintf (" %%% ds ", ancho), str)'. – kizzx2
@ kizzx2: para esta tarea en particular , hay una solución alternativa: la sintaxis de la cadena de formato permite que el ancho o la precisión sean reemplazados por un asterisco, en cuyo caso lo tomará de un argumento adicional que precede al argumento principal: 'Printf.sprintf"% * s "width str'; esta sintaxis también está disponible en C99, Perl, Python, Ruby, Go, etc. Pero, por supuesto, este es solo un caso particular, para otras cosas puede que no tenga suerte. Hay un operador '^^' en OCaml para anexar formatos, pero aún necesita formatos para agregar, en primer lugar, así que no sé qué tan útil es. – newacct