X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=topics%2Fweek8_monads_and_modules.mdwn;h=4983558304e362de19fd9493d27d94f9042e84bd;hp=fa232f3703e39c22fc80d5149b5f264c614a4b59;hb=9d942dc43c5451d2ba0ed927de13e93ad95c24b6;hpb=ff2bda4199473fb8cf195500e3212e3293919f09 diff --git a/topics/week8_monads_and_modules.mdwn b/topics/week8_monads_and_modules.mdwn index fa232f37..49835583 100644 --- a/topics/week8_monads_and_modules.mdwn +++ b/topics/week8_monads_and_modules.mdwn @@ -357,7 +357,7 @@ The other useful OCaml special commands are: * `#load "path/to/file.cmo"` is the way to load a pre-compiled OCaml module. For most (but not all) system-supplied modules, this is unnecessary. For modules you compile yourself (you might not end up doing that, though for the full-featured version of the interpreter from last week's homework, we were guiding you towards doing that) it will be necessary. It looks for `path/to/file.cmo` underneath the various directories it knows about or you have told it about. Pathnames that begin with `/` are from the top of your disk. `.cmo` is one of the suffixes for binary files that OCaml knows about; there are others. * `#use "path/to/file.ml"` is something like an analogue to the previous command, except that in this case the files loaded are uncompiled source-code files. Also, OCaml reads these files more-or-less as though you had just typed them directly into the interactive session yourself. One interesting difference this involves is that `#load`ed files are *always* modules, that you still need to explictly `open`. (`open` is a part of the ordinary OCaml language, so it has no `#` prefix.) Whereas with `#use`d files, you may not need to do any `open`ing. That depends on whether the `#use`d file defines a symbol directly at its top level, or defines it inside a `module M = struct ... end`. - + ## Abstraction barriers ## Say that you have to write some implementation of sets (where the elements are of some specified type `elem`). There are various ways you could do this. One way is to just use simple `elem list`s. When you get a new `elem`, you just `cons` it to the front of the list without any special checking. That has some advantages: it's simple and fast to add new elements to the list. But also some disadvantages: it can make it slower to check whether other `elem`s are members of the list, and can make it more complex to define operations like `difference`. A second way is to use lists, but to curate them so as to ensure that the lists never contain duplicates. A third way is to curate the lists so as to ensure that they're additionally always sorted. A fourth implementation might just to be to implement a list as an `int`. If there are only a small finite number of `elem`s, then bit 0 of your `int` could be on if that `elem` belongs to the set, else off; bit 1 could be for the next `elem`; and so on. Another way that sets are often implemented are with trees. Here there is the possibility that different concrete trees, for example `Branching (Leaf 2, Branching (Leaf 3, Leaf 5))` and `Branching (Branching (Leaf 2, Leaf 3), Leaf 5)`, might represent the same set.