Joy of OCaml
December 3, 2016 Leave a comment
I have spent most of last week with my Emacs editor and the OCaml development environment. Since I have some OCaml code to complete I will add more details soon.
Suffice it to say that this setup taxed me so much. OPAM does not seem to install easily in Windows. As is my wont in such cases I started with Cygwin and after two days switched to a Ubuntu VM. I didn’t think I was gaining much by reporting Cygwin permission issues to owners of OPAM Windows installers.
Emacs company mode for autocompletion
The toolchain includes company as well as Merlin
and Tuareg.
Utop is a toplevel for OCaml
Emacs elisp
It looks like this at this time and I use Gist because WordPress does not support Lisp or OCaml or Haskell yet. Filed a support ticket.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(package-initialize) | |
(load "/home/mohan/.opam/4.02.1/share/emacs/site-lisp/tuareg-site-file") | |
(let ((opam-share (ignore-errors (car (process-lines "opam" "config" "var" | |
"share"))))) | |
(when (and opam-share (file-directory-p opam-share)) | |
;; Register Merlin | |
(add-to-list 'load-path (expand-file-name "emacs/site-lisp" opam-share)) | |
(autoload 'merlin-mode "merlin" nil t nil) | |
;; Automatically start it in OCaml buffers | |
(add-hook 'tuareg-mode-hook 'merlin-mode t) | |
(add-hook 'caml-mode-hook 'merlin-mode t) | |
;; Use opam switch to lookup ocamlmerlin binary | |
(setq merlin-command 'opam))) | |
(company-mode) | |
(add-to-list 'load-path "/home/mohan/.opam/4.02.1/share/emacs/site-lisp") | |
(require 'ocp-indent) | |
(autoload 'utop-minor-mode "utop" "Minor mode for utop" t) | |
(autoload 'utop-setup-ocaml-buffer "utop" "Toplevel for OCaml" t) | |
(autoload 'merlin-mode "merlin" "Merlin mode" t) | |
(utop-minor-mode) | |
;; Important to note that setq-local is a macro and it needs to be | |
;; separate calls, not like setq | |
(setq-local merlin-completion-with-doc t) | |
(setq-local indent-tabs-mode nil) | |
(setq-local show-trailing-whitespace t) | |
(setq-local indent-line-function 'ocp-indent-line) | |
(setq-local indent-region-function 'ocp-indent-region) | |
(custom-set-variables | |
;; custom-set-variables was added by Custom. | |
;; If you edit it by hand, you could mess it up, so be careful. | |
;; Your init file should contain only one such instance. | |
;; If there is more than one, they won't work right. | |
'(package-selected-packages (quote (company)))) | |
(custom-set-faces | |
;; custom-set-faces was added by Custom. | |
;; If you edit it by hand, you could mess it up, so be careful. | |
;; Your init file should contain only one such instance. | |
;; If there is more than one, they won't work right. | |
) | |
; Make company aware of merlin | |
(with-eval-after-load 'company | |
(add-to-list 'company-backends 'merlin-company-backend)) | |
; Enable company on merlin managed buffers | |
(add-hook 'merlin-mode-hook 'company-mode) |
More about OCaml code later. This creates an associative list of tuples containing characters and the number of times they occur in a String. MultiSet is a module that is not shown either but as I mentioned I have more to write about this wonderful programming language.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let insert l a = | |
if List.mem_assoc a l | |
then | |
let n = List.assoc a l in (a, n+1)::(List.remove_assoc a l) | |
else (a, 1)::l | |
let letters (word : string) : char MultiSet.t = | |
let rec insert (l : char MultiSet.t) (c : string) (i : int) : char MultiSet.t = | |
if ( String.length c > 1 ) then | |
insert ( MultiSet.insert l (String.get c i) ) ( String.sub c 1 ((String.length c) – 1) ) 0 | |
else | |
MultiSet.insert l (String.get c 0) | |
in insert MultiSet.empty word 0 | |
;; |