PDA

View Full Version : my first o'caml function


kmj
09-10-2002, 10:50 AM
let rec dot_product a b =
match a with
[] -> (match b with [] -> 0)
| ah::at ->
(match b with
bh::bt -> ah*bh + dot_product at bt);;


It returns warnings due to "unexhausted matches" which is fine for right now, because those will occur when a person tries to compute the dot product of two incongruent vectors; and anyway, I haven't learned how to raise my own exceptions yet. In fact, this function displays the full extent of my current knowledge of O'Caml. Clearly, I have alot to learn. It also displays the power of functional programming; how much can be done with so little syntax.

Anyway, to use this function, simply supply two arrays of equal lengths, which it will treat as vectors...


# dot_product [1;2;3] [4;0;1];;
- : int = 7


This is a starter to dru's competition, if you haven't noticed. :)

jemfinch
09-10-2002, 12:40 PM
First, you're working with lists, not arrays :) Arrays use the [| 1; 2; 3; |] syntax.

You never really want a non-exhaustive match in your program; instead, raise a nice exception (so clients of your code get something better than MatchFailure when the don't use it correctly)


let rec dot_product a b =
match a, b with
| [], [] -> 0
| ah :: ht, bh :: bt -> ah * bh + dot_product at bt
| _ -> invalid_arg "dot_product: lists must be of equal length"


Jeremy

jemfinch
09-10-2002, 12:45 PM
Also, you could make this tail recursive:


let dot_product a b =
let aux acc a b =
match a, b with
| [], [] -> acc
| at :: ah, bt :: bh -> aux (acc + ah * bh) at bt
| _ -> invalid_arg "dot_product: lists must be of equal length"
in
aux 0 a b


Interestingly, you can do this to take advantage of currying:


let dot_product =
let aux acc a b =
match a, b with
| [], [] -> acc
| at :: ah, bt :: bh -> aux (acc + ah * bh) at bt
| _ -> invalid_arg "dot_product: lists must be of equal length"
in
aux 0


Cool, huh?

:)

Jeremy

kmj
09-10-2002, 02:45 PM
yes; very cool. Thanks for the tips! (also thanks for showing me how to raise an exception!).

jemfinch
09-10-2002, 05:22 PM
Actually, invalid_arg is a function; it is equivalent to this:

exception Invalid_argument of string
let invalid_arg s =
raise (Invalid_argument s)


That's how you actually raise an exception :) invalid_arg is a helper function. Also check into "failwith".

Jeremy

kmj
09-10-2002, 09:39 PM
danke.

:) Hmm. I probably won't have much time to play with *ml until next weekend.

(oh, if anyone thinks I should stick with O'Caml rather than follow jemfinch's personal preference and learn SML instead; let me know, and let me know why!!! :) )

Danke

GnuVince
09-10-2002, 11:06 PM
Well, from what I saw on Doug Bagley's shootout page, O'Caml code is much shorter than SML code, so that might be an argument. Also, it seems to me that O'Caml is a bit more popular and that there are more libraries available (LablGTK, LablGL, pcre, etc.) But you get to decide!

jemfinch
09-11-2002, 12:45 AM
If you were looking at his MLTon examples, he puts all the module code into the same file since MLTon doesn't support separate compilation (it's a whole-program-optimizing compiler).

Other than that, there shouldn't be a significant length difference between SML and O'Caml.

Jeremy