* Re: [Caml-list] How an exception could be an argument
2012-02-17 18:16 [Caml-list] How an exception could be an argument Pierre-Alexandre Voye
@ 2012-02-17 18:33 ` Edgar Friendly
2012-02-17 18:49 ` Vincent Aravantinos
2012-02-17 19:31 ` Tiphaine Turpin
2 siblings, 0 replies; 4+ messages in thread
From: Edgar Friendly @ 2012-02-17 18:33 UTC (permalink / raw)
To: Pierre-Alexandre Voye; +Cc: caml-list
[-- Attachment #1: Type: text/plain, Size: 1619 bytes --]
Here is an example of giving an exception as an argument to a function:
let run_or ~cmd ~err = if Sys.command cmd <> 0 then raise err
and an example usage:
let config_fail = Failure ("Could not configure " ^ p.id) in
run_or ~cmd:("sh configure" ^ config_opt) ~err:config_fail;
The problem with your code seems to be that you're passing in a result, so
the exception is being raised outside your try...with block. OCaml's eager
evaluation means that you'll probably have to pass in a function and an
argument (or just a unit function), meaning that your <|||> will be much
uglier:
let (<|||>) (f,x) (g,y) = try f x with Nothing -> g y
((fun () -> raise Nothing), ()) <|||> ((fun str -> str), "ii")
E.
On Fri, Feb 17, 2012 at 1:16 PM, Pierre-Alexandre Voye <ontologiae@gmail.com
> wrote:
> Hello, I'm trying to implement a scala concept "partial application" in
> which one can chains pattern matching function. If the first failed, the
> second is tried.
> It seems it is impossible to give an exception as argument to a function.
>
>
>
> exception Nothing;;
>
> let (<|||>) a b = try a
> with
>
> | Nothing -> (try b
> with
>
> | Nothing -> raise
> Nothing);;
>
> val ( <|||> ) : 'a -> 'a -> 'a = <fun>
>
>
>
> (raise Nothing) <|||>
> "jj";;
>
> Exception: Nothing.
>
>
> But if I try :
> try (raise Nothing)
> with
>
> | Nothing -> (try
> "jj"with
>
> | Nothing -> raise
> Nothing);;
>
> - : string = "jj"
>
> Is there a workaround ?
>
>
> Regards,
> P-A
> --
> ---------------------
> https://twitter.com/#!/ontologiae/
> http://linuxfr.org/users/montaigne
>
>
[-- Attachment #2: Type: text/html, Size: 5284 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] How an exception could be an argument
2012-02-17 18:16 [Caml-list] How an exception could be an argument Pierre-Alexandre Voye
2012-02-17 18:33 ` Edgar Friendly
@ 2012-02-17 18:49 ` Vincent Aravantinos
2012-02-17 19:31 ` Tiphaine Turpin
2 siblings, 0 replies; 4+ messages in thread
From: Vincent Aravantinos @ 2012-02-17 18:49 UTC (permalink / raw)
To: caml-list
The arguments are evaluated before being passed to the function.
So in your first test, "Nothing" is raised before even entering "<|||>".
In the second case you're circumventing this by copying directly "raise
Nothing" in the body of the function: this copy-pasting is not
equivalent since you now force the evaluation of "raise Nothing" to
happen within the scope of "try".
* The following could be a workaround:
# let (<|||>) (f1,arg1) (f2,arg2) = try f1 arg1 with Nothing -> try f2
arg2 with Nothing -> raise Nothing;;
val ( <|||> ) : ('a -> 'b) * 'a -> ('c -> 'b) * 'c -> 'b = <fun>
# ((fun _ -> raise Nothing),()) <|||> ((fun _ -> "jj"),());;
- : string = "jj"
It looks a bit heavy on this example because we are working with constants.
But generally the constants come from some function application so it
can fit in a not-so-ugly way in real code.
* If you don't care about the infix, the following induces less parentheses:
# let try_or_try f1 arg1 f2 arg2 = try f1 arg1 with Nothing -> try f2
arg2 with Nothing -> raise Nothing;;
val try_or_try : ('a -> 'b) * 'a -> ('c -> 'b) * 'c -> 'b = <fun>
# try_or_try (fun _ -> raise Nothing) () (fun _ -> "jj") ();;
- : string = "jj"
* Note that you can simplify the second try since "try blah with Nothing
-> raise Nothing" is actually equivalent to "blah"
This yields:
# let (<|||>) (f1,arg1) (f2,arg2) = try f1 arg1 with Nothing -> f2 arg2;;
val ( <|||> ) : ('a -> 'b) * 'a -> ('c -> 'b) * 'c -> 'b = <fun>
On 02/17/2012 01:16 PM, Pierre-Alexandre Voye wrote:
> (raise Nothing) <|||> "jj";;
> Exception: Nothing.
>
> But if I try :
> try (raise Nothing) with
> | Nothing -> (try "jj"with
> | Nothing -> raise Nothing);;
> - : string = "jj"
--
Vincent Aravantinos
Postdoctoral Fellow, Concordia University, Hardware Verification Group
http://users.encs.concordia.ca/~vincent
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] How an exception could be an argument
2012-02-17 18:16 [Caml-list] How an exception could be an argument Pierre-Alexandre Voye
2012-02-17 18:33 ` Edgar Friendly
2012-02-17 18:49 ` Vincent Aravantinos
@ 2012-02-17 19:31 ` Tiphaine Turpin
2 siblings, 0 replies; 4+ messages in thread
From: Tiphaine Turpin @ 2012-02-17 19:31 UTC (permalink / raw)
To: caml-list
[-- Attachment #1: Type: text/plain, Size: 2535 bytes --]
This behavior is expected given than OCaml is strict, and your operator
<|||> would be an ordinary function (unlike || and &&). You have to use
either functions (or lazy values) instead of expressions, or options
instead of exceptions.
Tiphaine
Le 17/02/2012 19:16, Pierre-Alexandre Voye a écrit :
> Hello, I'm trying to implement a scala concept "partial application"
> in which one can chains pattern matching function. If the first
> failed, the second is tried.
> It seems it is impossible to give an exception as argument to a function.
>
>
>
> exception Nothing;;
>
> let (<|||>) a b = try a
> with
>
> | Nothing -> (try b
> with
>
> | Nothing -> raise
> Nothing);;
>
> val ( <|||> ) : 'a -> 'a -> 'a = <fun>
>
>
> (raise Nothing) <|||>
> "jj";;
>
> Exception: Nothing.
>
>
> But if I try :
> try (raise Nothing)
> with
>
> | Nothing -> (try
> "jj"with
>
> | Nothing -> raise
> Nothing);;
>
> - : string = "jj"
>
> Is there a workaround ?
>
>
> Regards,
> P-A
> --
> ---------------------
> https://twitter.com/#!/ontologiae/ <https://twitter.com/#%21/ontologiae/>
> http://linuxfr.org/users/montaigne
>
[-- Attachment #2: Type: text/html, Size: 4884 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread