amuletml / amulet

An ML-like functional programming language
https://amulet.works/
BSD 3-Clause "New" or "Revised" License
326 stars 15 forks source link

How to pattern-match on specific exception type? #232

Closed Lupus closed 4 years ago

Lupus commented 4 years ago

I'm lost on how to do that. Looking at try_ in exception.ml I figured out how to catch any exception, but if I have my own kind of exception, how can I catch specifically it?

plt-amy commented 4 years ago

Just add a type signature to the handler parameter of catch

plt-amy commented 4 years ago

Sorry, wrong button there.

catch (fun () -> (* some work *)) (fun (x : some exception) -> ...)
(* catches any exception *)
catch (fun () -> (* some work *)) (fun (x : my_exception) -> ...)
(* only catches my_exception *)
Lupus commented 4 years ago

I'll give it a try today. Thanks!

Lupus commented 4 years ago

So far I'm unsuccessful at solving this. That's what I tried:

  module Error = begin
    open Exception

    type t = Decode_error of string
    deriving instance typeable t

    instance exception t begin
      let describe_exception (Decode_error x) = "Json decode error: " ^ x
    end

  end

  (* ... *)
  Exception.catch
  (fun () ->
    (* do stuff *)
  )
  (fun (Error.Decode_error msg) ->
    (* do something with msg *)
  )
Lupus commented 4 years ago

Ah, and the error from the compiler:

 json.ml[138:26 ..141:7]: error (E2018)
  No instance for exception Error.t arising from use of the expression
    │ 
138 │     | Some (_, value) -> Exception.catch
    │                          ^^^^^^^^^^^^^^^

The following message has a detailed explanation: 2018.
Try 'amc explain 2018' to see it
Lupus commented 4 years ago

Explicit type annotation does not change anything.

plt-amy commented 4 years ago

Try this instead:

let open Error in
Exception.catch
  (fun () -> (* stuff *))
  (fun (Decode_error msg) -> (* do something with msg *))