OCaml: get value's type name - ocaml

Is is possible to print value's name in OCaml, for example if I have
type my_type =
| MyType_First of int
| MyType_Second of string
and then do something like:
let my_value = MyType_First 0 in
print_string ("my_value is of type " ^ String.from_type my_value ^ ".\n";
can I get "my_value is of type MyType_First." ?
Thank you.

Monomorphic solution:
let from_type = function
| MyType_First _ -> "MyType_First"
| MyType_Second _ -> "MyType_Second"
Polymorphic solution: none. (AFAIK, lexical tokens corresponding to constructors are not recorded in the bytecode/binary, even when debugging flags are specified. The only thing one could do is to print the integer ‘identifier’ for the constructor, using some dark Obj.magic.)

What you want is a simpler form of generic print and is not available in OCaml as such, but some workarounds exist - e.g. deriving.

Related

Ocaml Conversion String to int to char

I need to implement this function somewhere
String.get: string -> int -> char
I have tried this one but it does not seem to work
let String.get = fun x -> char_of_int(int_of_string x) ;;
The error I get is:
let String.get = fun x -> char_of_int(int_of_string x) ;;
^^^
Error: Syntax error
String.get is a syntax to denote the function get in module String. The syntax can not be used to (re)define a function as you wrote.
The function is documented here:
val get : string -> int -> char
String.get s n returns the character at index n in string s. You can also write s.[n] instead of String.get s n.
Raise Invalid_argument if n not a valid index in s.
What you are trying to implement is different, you are trying to read, from the string, an integer, and then convert it to a digit char (?)
Depending on what your actual requirements are, you might be asked to reimplement String.get on your own, so for example you would pick a different name in your current module (for now, this is sufficient, you don't need to bother about modules):
let char_at s n = ...
Or maybe you do actually need to convert from an integer. Please clarify your question.

Printing user defined types in Ocaml

I am defining a new type which is basically a string. How to print the value ?
# type mytp = Mytp of string;;
type mytp = Mytp of string
# let x = Mytp "Hello Ocaml";;
val x : mytp = Mytp "Hello Ocaml"
# print_endline x;;
Error: This expression has type mytp but an expression was expected of type
string
#
This question already has answer here.
There is another question similar to this, which I had went through before asking the question, however I was not clear (maybe because I am a complete newbie. Other newbies might face similar confusion.) how to solve the problem from the accepted answer.
The type of print_endline is string -> unit. So you can't pass a value of type mytp.
You can write a function to print a value of type mytp:
let print_mytp (Mytp s) = print_endline s
You can write a function to convert mytp to string:
let string_of_mytp (Mytp s) = s
Then you can print like so:
print_endline (string_of_mytp x)
OCaml will not allow you to use mytp where string is expected, or vice versa. This is a feature, not a bug.

OCaml function name as string

I sometimes write functions that make the assumption that some arguments cannot occur. If they do, this is a bug and I fail:
let foo = function
| 0 -> ()
| _ -> failwith "foo: bad argument"
If I rename the function later on, I have to remember to also change the string. Is there a way to do this in a more systematic manner? My mind wanders around solutions like
| _ -> failwith (FUNCTION_NAME ^ ": bad argument")
where FUNCTION_NAME is a string variable that the compiler or interpreter will instantiate. But I have no idea whether something like this even works in OCaml. If not, is there a best practice?
There is a set of values available for debugging and error reporting.
OCaml 4.12 introduced __FUNCTION__:
val __FUNCTION__ : string
__FUNCTION__ returns the name of the current function or method, including any enclosing modules or classes.
They might be useful if you don't want to use assert false as suggested by #SteveVinoski.
__LOC__ : string
__FILE__ : string
__LINE__ : int
__MODULE__ : string
__POS__ : string * int * int * int
There are also fancier forms that you can use to wrap an expression to determine its extent in the source.
These are documented in the Stdlib module.
I think you should try as much as possible to use more specific types so that the compiler can prevent you from calling your functions with invalid input.
If you really don't find a way to tell the type system what you want, try harder, and if you really can't, then use assert which as Steve told you will give you some precious debugging information (file and line number are much more useful than function name since chances are high your function doesn't have a name).
Since 4.12.0, __FUNCTION__ will return the function name.
There are also a number of other debugging variables defined in Stdlib:
val __LOC__ : string
val __FILE__ : string
val __LINE__ : int
val __MODULE__ : string
val __POS__ : string * int * int * int
val __FUNCTION__ : string
val __LOC_OF__ : 'a -> string * 'a
val __LINE_OF__ : 'a -> int * 'a
val __POS_OF__ : 'a -> (string * int * int * int) * 'a

sml suppress warnings for intentionally nonexhaustive pattern matching

Suppose I have a datatype like:
datatype location = Safe of string | Dangerous of string * int;
And in this hypothetical example, I want to write a function that will only ever be passed a Safe str and never a Dangerous(str, num):
fun send_kids (Safe address) = ...
Is there any way to suppress the warnings? Tell SML I know tis nonexhaustive?
stdIn:1.6-1.29 Warning: match nonexhaustive
Safe s => ...
Not directly. You "tell" SML by making it exhaustive with a failure case:
fun sendKinds (Safe address) = ...
| sendKinds _ = raise Fail "sendKinds"

Idea working in types

Please see details in My previous question
1) cpf0.ml:
type string = char list
type name = string
type symbol =
| Symbol_name of name
2) problem.ml:
type symbol =
| Ident of Cpf0.string
In this problem.ml it has two definitions for type string, and surely it's giving me an error, but is it posible that I can make them have a same type? I need an idea.
module Str = struct type t = string end;;
module StrOrd = Ord.Make (Str);;
module StrSet = Set.Make (StrOrd);;
module StrMap = Map.Make (StrOrd);;
module SymbSet = Set.Make (SymbOrd);;
let rec ident_of_symbol = function
| Ident s -> s
let idents_of_symbols s =
SymbSet.fold (fun f s -> StrSet.add (ident_of_symbol f) s) s StrSet.empty;;
This expression has type Cpf0.string = char list but an expression was expected of type Util.StrSet.elt = string
You can use the name "string" for different types in different modules if you like, though (as Basile Starynkevitch points out) it's confusing. It would be better to pick a different name. If you really need to reuse the name, you can specify the module every time. If you don't specify a module, you'll get the predefined meaning (or the meaning from the innermost opened module).
It seems to me the problem in your quoted code is that this line:
module Str = struct type t = string end;;
doesn't specify a module name for string, so it refers to the predefined string. It seems possible you wanted to say:
module Str = struct type t = Cpf0.string end;;
It's hard to tell, however. There's not enough context for me to really understand what you're trying to do.
string is a predefined type in Ocaml (ie in the Pervasives module); it is e.g. the type of string literal constants like "this string". Use some other name (otherwise you, and any one reading your code, will be very confused)