How to convert non-built-in types to string in Ocaml?

ocaml

Solution

You want to pretty print symbolic expressions, with the ml syntax. There are libraries to deal with so called sexp, but I never used them, I cannot comment on their uses, and it's probably not what you want, as it would sidestep the purpose of the exercise.

I think you're somewhat close with what you already have, but there are some syntactic errors in your code. I'll give you a bunch of advices to help you close the gap.

First, regarding the OCaml syntax:

Recall that you don't need to use parentheses for your function argument. The general syntax for a function definition is:

let fun_name arg1 arg2 arg3 = function_body

if you write

let fun_name (arg1,arg2,arg3) = ...

you are actually defining a function taking 1 argument, which is itself a tuple of 3 values.

Within an expression, you can define local values using the `let ... in` construct, just like when you define top level values (like I did above). If these value definitions aren't inter-dependant, you can use the `and` keyword between several value definitions.

For instance,

let x = 1 
and y = "a" in
...

would define 2 values `x` and `y` which may be used in the subsequent code.

In your code

The types you have give a little symbolic expression language, with which you can define expressions like the one you give in example:

"x:int = if true then 3 else 5" would be:

Id("x", 
   Int, 
   (If (Const (1, Bool), 
        Const (3, Int), 
        Const (5, Int))))

Indeed, you need to go through that value recursively, and combine the returned strings into a bigger string. Alternatively, you could use a string list, and do the string concatenation at the end. Looking at that example, you probably can see how this would work:

"x" ^ (":" ^ "int") ^ "=" ^ ("if" ^ ("true") ^ "then" ^ ("3") ^ ("5"))

You can see the different sub expressions patterns in the above. I used parentheses to denote them.

In your toString function, there are 3 undefined values:

- `formatter` (a function taking a 3-tuple of type `string * exp * exp`)

- `formatDec1` (another function taking a 3-tuple of type `exp * exp * exp`)

- `formatIf` (same as `formatDec1`)

You used the keyword `rec` in your `toString` function definition, indicating that the function is recursive. In my opinion, you don't need the 3 functions above (are they a part of your initial assignment, or did you define them by yourself?), but just the `toString` function and string concatenation there.

the `App` arm of your `exp` type is very general: you can define application of any number of arguments, so your string conversion code should take that possibility in account. You could use some list function (`fold_left` comes to mind) to take care of it.

Problem

I'm trying to write a module that convert something like x:int = if true then 3 else 5 to a string Here's the code I have so far ``` module Ast = struct type typ = Bool | Int type var = A | B | C | D | E | F type exp = Const of int * typ | App of string * exp list | If of exp * exp * exp | And of exp * exp | Or of exp * exp | Id of var * typ * exp let rec toString (t) = let formatDec1(va,ty,e) = ??? match t with Const(n, _) -> print_int n | App(id, [e1; e2]) -> formatter(" " ^ id ^ " ", e1, e2) | App(id, [e1]) -> formatter(" " ^ id ^ " ", e1, Const(0, Int)) | App(id, _) -> formatter(" " ^ id ^ " ", Const(0, Int), Const(0, Int)) | If(e1, e2, e3) -> formatIf(e1, e2, e3) | And(e1, e2) -> formatter(" && ", e1, e2) | Or(e1, e2) -> formatter(" || ", e1, e2) | Id(va,ty,e) -> formatDecl(va,ty,e) end ``` I'm still a beginner in OCaml and couldn't find anything about converting to a string online. Thanks!

Original source