2017-01-24 3 views
0

Ich habe eine Funktion mit der folgenden Signatur:Funktion Wrapper/Dekorateur in OCaml

val func : a -> b -> c -> d -> e -> f -> unit 

und manchmal wirft es Ausnahmen. Ich möchte den Kontrollfluss ändern, so dass es wie folgt aussieht:

val funcw : a -> b -> c -> d -> e -> f -> [ `Error of string | `Ok of unit ] 

So wie ich es versucht Verpackung ist hässlich: eine andere Funktion machen, funcw, welche die gleiche Menge von Argumenten entgegennimmt, gilt func zu ihnen, und tut try/with. Aber es muss einen besseren Weg geben. Gedanken?

Antwort

1

Sie können f einen Parameter der Wrapper-Funktion machen. Das ist ein bisschen allgemeiner.

let w6 f a b c d e g = 
    try `Ok (f a b c d e g) with e -> `Error (Printexc.to_string e) 

A gewickelt Version von func ist dann (w6 func)

Dieser Wrapper arbeitet für curried Funktionen von 6 Argumente, wie Ihr func. Man kann nicht wirklich ein einzelnes Wrapper für alle eine unterschiedliche Anzahl von Argumenten definieren (wie sie verschiedene Typen haben), aber Sie können eine Familie von Wrapper für eine unterschiedliche Anzahl von Argumenten wie folgt definieren:

let w1 f x = try `Ok (f x) with e -> `Error (Printexc.to_string e) 
let ws f x y = 
    match f x with 
    | `Ok f' -> (try `Ok (f' y) with e -> `Error (Printexc.to_string e)) 
    | `Error _ as err -> err 
let w2 f = ws (w1 f) 
let w3 f x = ws (w2 f x) 
let w4 f x y = ws (w3 f x y) 
let w5 f x y z = ws (w4 f x y z) 
let w6 f x y z w = ws (w5 f x y z w) 

Es könnte sein, ein aufgeräumteres Schema, aber das scheint ziemlich gut zu sein.

+0

Sorry, ich merkte, dass ich 2 'f's hatte (eine eine Funktion und eine eine Art). Geändert zu 'func' und' funcw'. Ich würde diese Art von Lösung lieber vermeiden, da sie den einzigen Wahrheitspunkt entfernt, für den die Argumente "func" brauchen. – tekknolagi

+0

FWIW-Typen und -Werte belegen unterschiedliche Namespaces. Sie können eine Funktion namens f und einen Typ namens f haben. –

+0

Ah, danke. Geändert, um es irgendwie klarer zu machen. – tekknolagi