简体   繁体   中英

Dealing with circular dependencies in OCaml

I'm writing an interpreter for an experimental language. Three of the main constructs of the language are definitions, statements, and expressions. Definitions can contain statements and expressions, statements can contain definitions and expressions, and one kind of expression can contain statements. I represent all of these using union types so I can easily use pattern matching on them. Ideally, I would like to put the code for these in different files, but OMake complains about circular dependency issues. As far as I know, circular type definitions across modules are not allowed.

The only way I know of to solve this is to define all three types at once:

type defn = ...
and stmt = ...
and expr = ...

It seems like this requires all the code for types to be in the same file. Is there any way around this? How do you deal with circular definitions in your code?

Recursive definitions need to appear in the same file. If you want to separate definitions, statements, and expressions into separate modules, you can do so using recursive modules , but they will still need to appear in the same file. DAG-ifying inter-file dependencies is one of the annoyances of OCaml.

This is easily solved by parameterizing your types over the types they refer to:

type ('stmt, 'expr) defn = ...
type ('defn, 'expr) stmt = ...
type ('defn, 'stmt) expr = ...

This technique is called "untying the recursive knot" (in reference to Gordian's knot) and was described in an OCaml Journal article.

Cheers, Jon Harrop.

Another solution often used is to abstract the types in the interfaces. Since the types are abstract in the interfaces, these interfaces are not recursively dependent. In the implementations, you can specify the types, and since the implementations depend only on the interfaces, they are not recursive either.

The only problem is that, with this solution, you cannot anymore pattern-matching on these types outside of their implementation.

Personally, but it is probably a matter of taste, I like to have all the types of my program defined in one module (I think it helps in the readability of the program). So, this restriction of OCaml is not really a problem for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM