OCaml : Raise an error inside a match with structure - exception

In OCaml, I have a list of strings that contains names of towns (Something like "1-New York; 2-London; 3-Paris"). I need to ask the user to type a number (if they want London they have to type 2).
I want to raise an exception message saying that the town is not valid, if the person types for example "4", in the example.
I tried this, but it doesn't work :
let chosenTown = match int_of_string (input_line stdin) with
| x > (length listOfTowns) -> raise (Err "Not a valid town")
What's the good way to code "if the chosen number is bigger than the length of the list then raise the error" ??

Pattern can't contain arbitrary expressions. It can be a constant, a constructor name, record field inside curly braces, list, array, etc.
But patterns can be guarded, e.g.
match int_of_string (input_line stding) with
| x when x >= length listOfTowns ->
invalid_arg "the number is too large"
| x -> List.nth listOfTowns x

To complete the answer, patter matching relies on unification and does not expect assertion (it is not the equivalent of a switch in C or so).
The idea is that you provide different "shapes" (patterns) that your term (the thing you match on) could have.
For a list for instance:
match l with
| e :: e' :: r -> (*...*)
| e :: r -> (*...*)
| [] -> (*...*)
It also had a binding effect, if you pass on, say, [1] (a very small list indeed), it won't match e :: e' :: r, but will match e :: r and then e = 1 and r = [].
As ivg said, you can add conditions, as booleans this time, thanks to the keyword when.
However, when manipulating lists like this, I would go for a recursive function:
let rec find_town n l =
match l with
| t :: _ when n = 1 -> t
| _ :: r -> find_town (n-1) r
| [] -> raise (Err "Not a valid town")
This is basically writing again List.nth but changing the exception that it raises.

Related

What is wrong with this code for creating lists in OCaml?

I am trying to create a program in OCaml [randlist len max], which would generate an int list of length len with integers smaller than max.
I am wondering what is wrong with the following code:
let randlist dolzina maksimum =
let rec aux dolz maks acc =
match (List.length acc) with
| dolz -> acc
| _ -> aux dolz maks ((Random.int maks) :: acc)
in
aux dolzina maksimum []
This always returns an empty list and I do not understand why.
Another thing that confuses me is what goes wrong with the following code:
let randlist dolzina maksimum =
Random.self_init ()
let rec aux dolz maks acc =
match (List.length acc) with
| dolz -> acc
| _ -> aux dolz maks ((Random.int maks) :: acc)
in
aux dolzina maksimum []
As soon as I add the Random.self init () the whole code crashes. What exactly does Random.self_init do, when and how do I use it?
You are using match as if it is going to compare two integer values, but that's not how it works. This match:
Match List.length acc with
| dolz -> ...
Will always match the first case. The name dolz is a new variable that is bound to the length of the list. The outer definition of dolz is not relevant here, a pattern introduces new names.
If you want to compare two integer values, you should use if:
if List.length acc = dolz then
...
else
...
Pattern matching deconstructs values that match a pattern into smaller parts, it doesn't test equality. In other words, your first case
match List.length acc with
| dolz -> acc
reads: take the value returned by List.length acc, name it dolz in the right hand side of the arrow ->, and run the code after ->. Notice that this means that dolz matches any values.
This is why the compiler warns you that the second case
| _ -> aux dolz maks ((Random.int maks) :: acc)
is never used.
For your second question, the code cannot crash, since your code is not well-typed and thus cannot compile. Random.self_init initialize the seed of the PRNG. You should call it once in your program, and not at every calls of randlist.
What you're trying to accomplish can be implemented without having to calculate the length of the accumulated list. You just need to count the length parameter down by one on each iteration and return acc when it is less than or equal to 0.
let randlist count max =
let rec aux c m acc =
if c <= 0 then acc
else aux (c-1) m (Random.init max :: acc)
in
aux count max []
Of course, all of this is just a convoluted way to write:
let randlist count max =
List.init count (fun _ -> Random.int max)
Here the List.init function takes care of the iteration for us. Implementing an equivalent function may shed some light on how it works.
let list_init n f =
let rec list_init' n f acc =
if n <= 0 then acc
else list_init' (n-1) f (f (n-1) :: acc)
in
list_init' n f []

Raising meaningful exceptions in Ocaml

I would like to print a meaningful message when raising a defined exception in OCaml:
type t = A | B of int
exception Wrong of t
Say I have a function
let string_of_t = function
| A -> "A"
| B n -> ("B" ^ (string_of_int n))
Then I would like to have a function
val print_exception : ( 'a -> string ) -> a' exn -> string
so that I can define
let my_raise e =
print_endline ("Error: I got the unexpected value" ^ (print_exception string_of_t e));
raise e [???]
Is there such a function print_exception ?
The problem is not very well-posed (for instance, there is no a' exn type), but I hope my intent is understandable. I've seen that one can use [##deriving sexp] but this looks like some magic outside of the language, and there is probably something easier and within the language.
There are two ways. The first one is using Printexc, the second one would be to match all the exceptions you want to print and print accordingly, something like:
exception Zero of int
exception B of string
let pp ppf = function
| Zero d -> Format.fprintf ppf "Zero of %d" d
| B s -> Format.fprintf ppf "B of %s" s
| Not_found -> Format.fprintf ppf "Not found"
| _ -> Format.fprintf ppf "Your exception is in another castle"
let f n d = if d = 0 then raise (Zero d) else n / d
let () =
let n, d = (10, 0) in
try Format.printf "%d/%d is %d#." n d (f n d)
with e ->
Format.eprintf "%a#." pp e;
Format.eprintf "%s#." (Printexc.to_string e)
Will give
❯ ./exc
Zero of 0
Exc.Zero(0)
Combining the two seems to be the best solution to be able to customise some displays and let all the others be a default one:
let pp ppf = function
| Zero d -> Format.fprintf ppf "Zero of %d" d
| e -> Format.fprintf ppf "%s" (Printexc.to_string e)
In OCaml we don't have (yet) modular implicits so unless you use [##derive ...] you need to use one of the two solutions.
As a side-note, exceptions can be caught in a pattern matching:
let () =
let n, d = (10, 0) in
match f n d with
| r -> Format.printf "%d/%d is %d#." n d r
| exception e ->
Format.eprintf "%a#." pp e;
Format.eprintf "%s#." (Printexc.to_string e)
It does semantically the same as what I wrote before but it's better for call stacks (if I'm not mistaken)
[EDIT] Looks like I forgot a third solution, see #octachron's answer
If you want to log a meaningful message before raising, it seems to me that it might be simpler to combine the logging and exception raising in one function rather than trying to reconstruct an error message from a generic unknown exception after the fact. For instance, the following function
let log_and_raise exn fmt =
Format.kfprintf
(fun ppf -> Format.pp_print_newline ppf (); raise exn)
Format.err_formatter fmt
can be used like this
exception A of int
let test n = log_and_raise (A n) "Raising the exception (A %d)" n
and will raise the exception A n after printing the error message on stderr.

Need help understanding how this Haskell code works

I am trying to learn Haskell programming language by trying to figure out some pieces of code.
I have these 2 small functions but I have no idea how to test them on ghci.
What parameters should I use when calling these functions?
total :: (Integer -> Integer) -> Integer -> Integer
total function count = foldr(\x count -> function x + count) 0 [0..count]
The function above is supposed to for the given value n, return f 0 + f 1 + ... + f n.
However when calling the function I don't understand what to put in the f part. n is just an integer, but what is f supposed to be?
iter :: Int -> (a -> a) -> (a -> a)
iter n f
| n > 0 = f . iter (n-1) f
| otherwise = id
iter' :: Int -> (a -> a) -> (a -> a)
iter' n = foldr (.) id . replicate n
This function is supposed to compose the given function f :: a -> a with itself n :: Integer times, e.g., iter 2 f = f . f.
Once again when calling the function I don't understand what to put instead of f as a parameter.
To your first question, you use any value for f such that
f 0 + f 1 + ... + f n
indeed makes sense. You could use any numeric function capable of accepting an Integer argument and returning an Integer value, like (1 +), abs, signum, error "error", (\x -> x^3-x^2+5*x-2), etc.
"Makes sense" here means that the resulting expression has type ("typechecks", in a vernacular), not that it would run without causing an error.
To your second question, any function that returns the same type of value as its argument, like (1+), (2/) etc.

How to find maximum of function outputs with multipe inputs in one function?

I want a function maxfunct, with input f (a function) and input n (int), that computes all outputs of function f with inputs 0 to n, and checks for the max value of the output.
I am quite new to haskell, what I tried is something like that:
maxfunct f n
| n < 0 = 0
| otherwise = maximum [k | k <- [\(f, x)-> f x], x<- [0..n]]
Idea is that I store every output of f in a list, and check for the maximum in this list.
How can I achieve that?
You're close. First, let's note the type of the function we're trying to write. Starting with the type, in addition to helping you get a better feel for the function, also lets the compiler give us better error messages. It looks like you're expecting a function and an integer. The result of the function should be compatible with maximum (i.e. should satisfy Ord) and also needs to have a reasonable "zero" value (so we'll just say it needs Num, for simplicity's sake; in reality, we might consider using Bounded or Monoid or something, depending on your needs, but Num will suffice for now).
So here's what I propose as the type signature.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
Technically, we could generalize a bit more and make the Int a type argument as well (requires Num, Enum, and Ord), but that's probably overkill. Now, let's look at your implementation.
maxfunct f n
| n < 0 = 0
| otherwise = maximum [k | k <- [\(f, x)-> f x], x<- [0..n]]
Not bad. The first case is definitely good. But I think you may have gotten a bit confused in the list comprehension syntax. What we want to say is: take every value from 0 to n, apply f to it, and then maximize.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
maxfunct f n
| n < 0 = 0
| otherwise = maximum [f x | x <- [0..n]]
and there you have it. For what it's worth, you can also do this with map pretty easily.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
maxfunct f n
| n < 0 = 0
| otherwise = maximum $ map f [0..n]
It's just a matter of which you find more easily readable. I'm a map / filter guy myself, but lots of folks prefer list comprehensions, so to each his own.

F# type mismatch when sending infix operator as parameter

I'm learning F# and is doing an exercise that requires me to perform math operations on a stack of floats.
exception InterpreterError;;
type Instruction =
| ADD
| SUB
| MULT
| DIV
| SIN
| COS
| LOG
| EXP
| PUSH of float;;
type Stack = S of float list;;
let pop (S(s)) =
match s with
| [] -> raise InterpreterError
| x::_ -> (x,S(s));;
let push x (S(s)) : Stack = S(x::s)
let applyBin f s : Stack =
let (first, sGen1) = pop s
let (second,sGen2) = pop sGen1
push (f(first,second)) sGen2;;
let applyUni f s : Stack =
let (first, sGen1) = pop s
push (f(first)) sGen1;;
let intpInstr i s =
match i with
| ADD -> applyBin (+) s
| SUB -> applyBin (-) s
| MULT -> applyBin (*) s
| DIV -> applyBin (/) s
| SIN -> applyUni sin s
| COS -> applyUni cos s
| LOG -> applyUni log s
| EXP -> applyUni exp s
| PUSH(r) -> push r s;;
However, I'm getting a compiler error in the last function intpInstr on the infix operators (+, -, *, /) that I try to pass as arguments:
Type mismatch. Expecting a
float * float -> float
but given a
float * float -> 'a -> 'b
The type 'float' does not match the type ''a -> 'b'
Why does the operators become (+) : float -> float -> 'a -> 'b? I haven't been able to replicate this type in the interactive console.
All help appreciated.
With your definition of applyBin the parameter f has type (float * float) -> float i.e. it takes a single pair parameter and returns a float. This is due to the application f (first, second) in applyBin. The binary operators +, -, * and / all have type float -> float -> float so it looks like you intend that to be the type of f within applyBin. You can do this by removing the pair construction:
let applyBin f s : Stack =
let (first, sGen1) = pop s
let (second,sGen2) = pop sGen1
push (f first second) sGen2
If you're willing to invest into a custom composition operator, you could employ eta reduction and express the logic of the function application more succinctly.
let (>|>) f g = f >> fun (b, c) -> g b c
let applyUna f =
pop >|> fun first ->
push (f first)
let applyBin f =
pop >|> fun first ->
pop >|> fun second ->
push (f first second)
There are still two tupled arguments returned by the 'pop' operation. Their conversion to curried arguments enables partial application and avoids the need to name any of the stack states.