Using a bunch of generated OCaml files for which it would be simpler to define a top module's signature without using a .mli file the same way it is done for nested modules. For example in Mymodule.ml be able to write something like:
module self/this module : sig
... (* contents of the mli file *)
end =
struct
...
end
I couldn't find the syntax to do it though. Is it even possible?
You'd have to do the following. I really don't know why this is "easier", maybe you should give a few more details to point you in the right direction.
module X : sig ... end =
struct
...
end
include X
Related
I'm new in Modelica programming (I'm using OpenModelica and text editor on Ubuntu 1.8), and I have to define some units, one of these is min^(-1), and I did it writing " type min_1=Real(unit="min^(-1)"); " in a model file with .mo extension (in this file I have no equations, I have only units definitions), and in another Modelica file (a record file) I have only parameters definitions (no equations) e.g. parameter min_1 beta=0.002; , but when I run the entire model I have an error concerning only (at least apparently, because I have no other erros) this particular unit, beacuse it says that min_1 is not found the scope of the file that cointains only parameters definitions (but min_1 is present is this file, in fact, apparently, I don't have the same problem with other units I defined), so I am not able to understand what is the real problem with that beacuse the error is really vague. Before I tryed to define units, all parameters were defined as Real, and the model plotted perfectly, so I'm pretty sure that the only possible problem is located in these 2 files. (Naturally all Modelica files of my entire Model are located in the same folder).
To define my units file I wrote in a .mo file (a model file):
model def_units
type dlkg=Real(unit="dl/kg");
type mg_1=Real(unit="mg^(-1)");
type kg_1=Real(unit="1/kg");
type min_kg_pmol=Real(unit="min*kg/pmol");
type min_1=Real(unit="min^(-1)");
type mg_kg_min=Real(unit="mg/kg/min");
type mg_kg_min_pmol_l=Real(unit="mg/kg/min*pmol*l");
type mg_kg_min_pmol_kg=Real(unit="mg/kg/min*pmol*kg");
type mg_kg=Real(unit="mg/kg");
type pmol_kg_mg_dl=Real(unit="pmol/kg*(mg/dl)");
type pmol_kg_min_dl=Real(unit="pmol/kg*(min/dl)");
end def_units;
To define my parameters I wrote in a separate .mo file (a record file) this:
record param
parameter min_1 alpha=0.001 ;
parameter min_1 beta=0.002;
parameter dl_kg gamma=0.003;
parameter mg_kg_min delta=0.004;
/* [... ] */
/* many other parameters defined in this way */
/* [... ] */
end param;
I did not use/import any libraries, those are standard units of the International System, they are only kinda "concatenated" between them, and reading on Internet the only way I found to define something more specific, like in this case, was the way I wrote my code above (my supervisor also approved the way I defined my units).
What could be the problem in this case?
Please if you can, try to explain in a simply and specific way.
Any help and advice will be very appreciate.
Thanks in advance.
Seems to be working fine, but you need to import def_units elements in your param record or you need to define them as parameter def_units.min_1 beta=0.002;
I would also suggest changing def_units from a model to a package.
Read more about Modelica imports and different Modelica classes such as packages, records, models and blocks in the Modelica Specification on modelica.org or the Modelica Book: http://book.xogeny.com/.
File def_units.mo
model def_units
type dl_kg=Real(unit="dl/kg");
type mg_1=Real(unit="mg^(-1)");
type kg_1=Real(unit="1/kg");
type min_kg_pmol=Real(unit="min*kg/pmol");
type min_1=Real(unit="min^(-1)");
type mg_kg_min=Real(unit="mg/kg/min");
type mg_kg_min_pmol_l=Real(unit="mg/kg/min*pmol*l");
type mg_kg_min_pmol_kg=Real(unit="mg/kg/min*pmol*kg");
type mg_kg=Real(unit="mg/kg");
type pmol_kg_mg_dl=Real(unit="pmol/kg*(mg/dl)");
type pmol_kg_min_dl=Real(unit="pmol/kg*(min/dl)");
end def_units;
File param.mo
record param
import def_units.*; // you need to import all definitions from def_units!
parameter min_1 alpha=0.001 ;
parameter min_1 beta=0.002;
parameter dl_kg gamma=0.003;
parameter mg_kg_min delta=0.004;
/* [... ] */
/* many other parameters defined in this way */
/* [... ] */
end param;
File script t.mos
loadFile("def_units.mo"); getErrorString();
loadFile("param.mo"); getErrorString();
instantiateModel(param); getErrorString();
Running the script with the OpenModelica compiler OMC:
adrpo33#ida-0030 MINGW64 /c/home/adrpo33/dev/OMTesting/bugs/units
$ ~/dev/OpenModelica/build/bin/omc t.mos
true
""
true
""
"class param
parameter Real alpha(unit = \"min^(-1)\") = 0.001;
parameter Real beta(unit = \"min^(-1)\") = 0.002;
parameter Real gamma(unit = \"dl/kg\") = 0.003;
parameter Real delta(unit = \"mg/kg/min\") = 0.004;
end param;
"
""
I was here for something else but trying to write up my question, I realize there's no way I'm doing this right.
I've been using mirage and irmin for a little while, and as long as all the code stays in the Main module everything is great. But of course, it quickly becomes a ridiculously huge file, and trying to split it in modules drives me mad with types escaping their scopes and whatnot.
Instead of just passing console from start to some other functions, I have to put those other functions in a functor that will take the Mirage_types_lwt.CONSOLE as well as the actual console variable, which means everything ends up being in functors instantiated from start and passed around in an unreadable mess of code.
I'm having problems making a giant ugly module to store and pass all of this easily (to "isolate" the parts that need this mess from regular code), and I can't figure out how to declare something like this :
module type ContextConfig = sig
module Store
val clientctx : Client.ctx
....
end
let mkContextConfig (module Store : Repo) ctx =
(module struct
(module Store : Repo)
let clientctx = ctx
end : ContextConfig)
(Repo being a module I made to wrap around Irmin's functors).
This obviously doesn't work, and I tried so many syntaxes I'm guessing it's just not possible, that means I'm doing something very wrong ?
I'd love advice on the proper way to deal with all of those functors and types in a clean way, how do I pass around things like the console or a conduit without having to functorize and instantiate everything in the Main module just to pass it around after ?
Definitions like that are possible:
module type REPO = sig end
module type CONTEXT_CONFIG = sig
module Store : REPO
val client_ctx : int
end
let mkContextConfig (module Store : REPO) ctx =
(module struct
module Store = Store
let client_ctx = ctx
end : CONTEXT_CONFIG)
(With some uninteresting changes to make the code type check.)
I'm using menhir to generate a parser and right now, the parser.mli file that it generated from my parser.mly file looks like this:
(* The type of tokens. *)
type token =
(* ... huge ADT definition goes here ... *)
(* This exception is raised by the monolithic API functions. *)
exception Error
(* The monolithic API. *)
val start: (Lexing.lexbuf -> token) -> Lexing.lexbuf -> Types.ast
Is there a way to include more stuff in my parser's interface? In particular, I would like to be able to also export the datatype for my AST (which is currently in a separate Types module) and some functions that work with the token datatype (for example, a function to convert them back to strings).
I tried putting some Ocaml code after the %% in parser.mly but while that code shows up in parser.ml none of the functions I declared appear in parser.mli.
I have implemented a pretty-printer for a module. Currently I start up utop, load the dependencies then do #install_printer pp_custom;; where pp_custom is the pretty-printer.
I would like to automate this so that I can have it in a way that is similar to the lacaml library where the pretty-printer for the matrix is "installed" by default.
How would I go about to doing that?
In short, you need to run #install_printer directive whenever you load your library in the top. I'm using the following code to evaluate code in the toplevel:
open Core_kernel.Std
open Or_error
let eval_exn str =
let lexbuf = Lexing.from_string str in
let phrase = !Toploop.parse_toplevel_phrase lexbuf in
Toploop.execute_phrase false Format.err_formatter phrase
let eval str = try_with (fun () -> eval_exn str)
It depends on Core_kernel, but you can get rid of this easily, by just using eval_exn instead of eval (the last one wraps a possible exception into the Or_error monad). Once you've got the eval function, it can be used to load your printers:
let () = eval (sprintf "#install_printer %s;;" printer)
where printer is the name of the pretty printing function (usually qualified with a module name). Usually, one put such code into the separate library, named library.top, where library is the name of your library.
For further automation, you can require all types, that you want to be auto-printable in toplevel, to register itself in a central registry, and then call all registered printers, instead of enumerating them by hand. To see all this working at once, you can take a look at the BAP library. It has a sublibrary called bap.top that automatically installs all printers. Each type that is desired to be printable implements Printable signature, using Printable.Make functor, that not only derives many printing functions from the basic definition, but also registers the generated pretty-printers in Core_kernel's Pretty_printer registry (you can use your own registry, this is just a set of strings, nothing more). When bap.top library is loaded into the toplevel (using require or load directive), it enumerates all registered printers and install them.
I'm working on a relatively large SML codebase. It was originally written to compile with MLton, but I'm now working with it under SML/NJ. I need to use RedBlackMapFn, which is defined in smlnj-lib.cm. However, I get an error:
elaborate/elaborate-bomenv.fun:9.20-9.27 Error: unbound signature: ORD_KEY
elaborate/elaborate-bomenv.fun:14.21-14.40 Error: unbound functor: RedBlackMapFn
elaborate/elaborate-bomenv.fun:32.20-32.27 Error: unbound signature: ORD_KEY
elaborate/elaborate-bomenv.fun:37.21-37.40 Error: unbound functor: RedBlackMapFn
So I assume that smlnj-lib.cm is not being pulled by CM. In an effort to fix this, I added $/smlnj-lib.cm to the sources.cm file in the directory that I'm working in. This causes a separate issue:
elaborate/sources.cm:25.1-25.18 Error: structure Random imported from $SMLNJ-LIB/Util/smlnj-lib.cm#243997(random.sml) and also from ./(sources.cm):lib/(sources.cm):basic/(sources.cm):random.sml
elaborate/sources.cm:25.1-25.18 Error: structure Queue imported from $SMLNJ-LIB/Util/smlnj-lib.cm#436143(queue.sml) and also from ./(sources.cm):lib/(sources.cm):basic/(sources.cm):two-list-queue.sml
No dice. I tried removing the Random structure that's coming from ./(sources.cm):lib/(sources.cm):basic/(sources.cm):random.sml, but it appears that it isn't equivalent to the one defined in the standard library, so I can't just substitute one for the other.
I'd like to use something like Python's import ... from ... as ...
mechanism to give a new name to the Random that's coming from the standard library, but CM's documentation doesn't offer any hints as to how I'd go about that.
How can I resolve a module naming conflict across multiple SML files?
I ended up splitting off the problematic file in to a separate .cm. The problem file here is elaborate-bomenv.{sig, fun}. The .cm file for this directory is sources.cm, which caused errors when it looked like:
Group
...
is
$/basis.cm
...
elaborate-bomenv.fun
elaborate-bomenv.sig
...
So instead, I made an elaborate-bomenv-sources.cm that looks like:
Group
signature ELABORATE_BOMENV
functor BOMEnv
is
$/smlnj-lib.cm
...
elaborate-bomenv.sig
elaborate-bomenv.fun
and changed the original sources.cm to read:
Group
...
is
$/basis.cm
...
./elaborate-bomenv-sources.cm
...
Which is ugly, but it works.