syntax error in function in a module, OCaml - module

Hi my following code gives a "Syntax Error" and i have no idea why...
Any basic mistake you can see?
(* ajouter_itineraire: itineraire -> plan -> plan *)
let ajouter_itineraire (i: itineraire) (p: plan) = match p with
| Vide ->[i]
| Ilist l ->if itineraire_existe(i.num) then
Err("Itineraire deja present") else i::p.Ilist
Err is an exception taking a string as parameter.

Your code tries to return the exception as a value. I think you want to say raise (Err "Itineraire deja present"). Also p.Ilist looks wrong. Most likely this should be just l.

Related

Cannot move io::Error out of Peekable Result

I'm just trying to propagate the IO error:
enum MyError {
EOF,
IO(std::io::Error),
}
fn peek_byte<R>(mut p: Peekable<Bytes<R>>) -> Result<u8, MyError>
where
R: Read,
{
match p.peek() {
None => Err(MyError::EOF),
Some(Err(e)) => Err(MyError::IO(*e)), // <==== error is here
Some(Ok(byte)) => Ok(*byte),
}
}
But, I get the following error:
error[E0507]: cannot move out of `*e` which is behind a shared reference
--> src/main.rs:17:41
|
17 | Some(Err(e)) => Err(MyError::IO(*e)),
| ^^ move occurs because `*e` has type `std::io::Error`, which does not implement the `Copy` trait
I actually understand all of this. I know why I'm getting the error, and what the error means. What I don't know is how to accomplish my task and propagate the IO error into my error type.
I have tried e, *e, e.clone(), *e.clone(), *(e.clone()), but they all either produce a "type mismatch" or a "cannot move" error.
The Peekable iterator holds ownership of the next value of its internal iterator and returns references via peek, but if you actually want the owned value you just call next as usual (which does advance the iterator but I think that's okay in this case since you're not actually consuming any content from the iterator but just trying to return an error):
use std::io;
use std::io::Bytes;
use std::io::Read;
use std::iter::Peekable;
enum MyError {
EOF,
IO(io::Error),
}
fn peek_byte<R>(mut p: Peekable<Bytes<R>>) -> Result<u8, MyError>
where
R: Read,
{
match p.peek() {
None => Err(MyError::EOF),
Some(Err(e)) => Err(MyError::IO(p.next().unwrap().unwrap_err())),
Some(Ok(byte)) => Ok(*byte),
}
}
playground

What is the cleanest way to return the error when matching a Result<T, E>? [duplicate]

This question already has answers here:
Is there any way of doing unwrap_or_return an Error (any error)
(1 answer)
What is this question mark operator about?
(4 answers)
Closed 2 years ago.
I'm calling a function that returns a Result<T, E> and I want to handle the Ok case but return the Err as is if an error is returned. What is the cleanest way to do this?
For example, I have:
fn example() -> Result<(), Error> {
match foo() {
Ok(v) => bar(v),
Err(e) => Err(e),
}
}
What are some alternate forms of writing this? It feels weird to re-wrap e in another Err in every call in the stack. Also, every call is basically 4 lines of boilerplate... I'm just looking for a way to simplify and make it more readable. My desire is to have it return the error if error, else process the result value.
Rust includes an 'error propagation' operator, ?. If the value of the Result it is called on is Ok it will unwrap and return the inner value. If the value is Err it will return from the function and pass the Err to the caller.
fn example() -> Result<(), Error> {
let v = foo()?;
bar(v);
}

Is there a way to "catch" errors in GAP?

Suppose I'm using a package function f that takes a single argument x and performs some error checking on that argument. Like, is x of the right type? Etc. And if there is an error then f(x) throws an error with Error().
Is there an easy way to write a wrapper function fCatch around f to catch that error, and say return false if f(x) throws an error but true otherwise? The naïve way to accomplish this same effect would be to copy the code for f and change all the Error(...); lines into a return false; and set a return true; at the end, but it's bad form to duplicate all the error-checking code.
As per Alexander Konovalov's comment, the following works, except the Error(...) message that f(x) triggers still prints.
fCatch := function(x)
local result;
BreakOnError := false;
result := CALL_WITH_CATCH(f, [ x ])[1];;
BreakOnError := true;
return result;
end;
A warning: the CALL_WITH_CATCH function, and any other function with an ALL CAPS name, is undocumented and intended to only be used internally in GAP.

How to display OK results

I am playing with the Elm examples, and I noticed the field example gives Result types. After getting stuck, I came up with this simplified case:
import Html exposing (text)
import String
f: Int -> Int
f x = x + 1
g: Result String Int -> Result String Int
g x = (Result.map f) x
main =
text ( toString ( g (String.toInt 5 ) ))
The result displays OK 6 and I would rather it display just 6 -- I know that toString takes any type and returns a string representaton of it. So maybe I can modify toString
if result is OK then I can print the numerical result
if the result is Err then I would like do some custom error message
Possibly this is the reason for the andThen since the + 1 operation can fail.
andThen : Result e a -> (a -> Result e b) -> Result e b
andThen result callback =
case result of
Ok value -> callback value
Err msg -> Err msg
The definition of andThen is exactly what it does... and is an instance of case.
Either with andThen or plain old case how do I fix my example? Even if I fix it myself, it might not be the most Elm-like solution with good error handling. So I am posting the question.
When a function returns a Result, you have a choice - you can also return a Result, in which case you can return Err(something) or Ok(something). This percolates your errors up to the calling function, which can decide what to do. The other way is you can return something that isn't a result, like a String or Html. If you go this second route, then you need to handle both possibilities of the Result and still return your String or Html.
So for example this function takes a result and returns a string. It handles both possibilities, returning a string even if the result was an Err.
foo: Result String Err -> String
foo myres =
case myres of
Ok(str) -> str
Err(e) -> "there was an error! uh oh"
Its kind of a question of how far up the hierarchy you want to go with your Result. Do you want the errors to percolate all the way up to the top level? Maybe your top level function is like this:
View: Model -> Html
View model =
case makeMyHtml(model) of
Ok(htm) -> htm
Err(e) -> renderSpecialErrorHtmlPage(e)
At any rate, to get rid of the 'Ok' in this case you can do this:
main =
let res = g (String.toInt 5 )
text ( toString ( Result.withDefault "g returned an error!" res))
If g returns Ok(6) then you get "6", but if it returns error you get "g returned an error!".

How to correctly implement error handling?

I am calling a function fit_circle that may or may not call the MESSAGE procedure. fit_circle calls a function poly_fit that may call the MESSAGE procedure, but also occasionaly produces a math error (there is nothing I can do about this).
Is it possible to contruct an error handler that will take care of all of these scenarios without returning to the interactive prompt? I have tried the following:
FUNCTION arb_funct,circular_data
CATCH, ERROR
IF ERROR NE 0 THEN BEGIN
CATCH, /CANCEL
print, 'An Error Occured'
return, []
ENDIF
circle_fit_result = fit_circle(circular_data)
return, circle_fit_result
END
However the error handler never triggers. The documentation only seems to mention looking for error handlers defined in procedures.
Works for me. Here is my example code:
pro mg_error_demo_helper2
compile_opt strictarr
a = b
end
pro mg_error_demo_helper1
compile_opt strictarr
mg_error_demo_helper2
end
pro mg_error_demo
compile_opt strictarr
catch, error
if (error ne 0L) then begin
catch, /cancel
print, 'An error occurred'
return
endif
mg_error_demo_helper1
end
When I run it, I get:
IDL> mg_error_demo
% Compiled module: MG_ERROR_DEMO.
error happened
IDL has three different types of "catchable" errors:
"Normal" Errors: These are the most common type of error to handle. They are thrown when message is called. Use catch or on_error to deal with them.
IO Errors: These happen when a conversion, disk read, memory, or other "IO" error occurs. Usually, these will also be caught by catch and on_error. When they aren't, use on_ioerror to deal with them.
Math Errors: These happen when you divide by 0, do certain math with NaN or infinity, etc. Deal with them using check_math and !except.
Here's an example of using all three in one program:
function arb_funct, circular_data
; handle normal errors
catch, error
if error ne 0 then begin
catch, /cancel
print, 'A normal error occured: ' + !error_state.msg
return, []
endif
; handle IO errors
on_ioerror, arb_funct__ioerror
if 0B then begin
arb_funct__ioerror:
print, 'An IO error occured: ' + !error_state.msg
return, []
endif
; clear math errors from previous routines
math_err = check_math(/print)
previous_except = !except
!except = 0
; do stuff
circle_fit_result = fit_circle(circular_data)
; handle math errors
math_err = check_math()
!except = previous_except
if math_err ne 0 then begin
print, 'A math error occured: ' + strtrim(math_err, 1)
return, []
endif
; and finally return
return, circle_fit_result
end
Here is an example of to what I referred:
FUNCTION some_function
;;--------------------------------------------------------------------------
;; Error handling [put towards beginning of routine]
;;--------------------------------------------------------------------------
CATCH, error_status
IF (error_status NE 0) THEN BEGIN
;; Cancel error handler
CATCH, /CANCEL
;; Print error message
PRINT, 'Error index: ', error_status
PRINT, 'Error message: ', !ERROR_STATE.MSG
;; Define return variable or how to handle error
;; --> I usually use a formatted output consistent with the expected
;; output, but here I will just use 0 for example.
dumb = 0
;; Return defined variable
RETURN,dumb
ENDIF
;;--------------------------------------------------------------------------
;; Main body of routine
;;--------------------------------------------------------------------------
blah = 0
; blah
; blah
; blah
;;--------------------------------------------------------------------------
;; Return to user
;;--------------------------------------------------------------------------
RETURN,return_variable
END
Hope that helps...