Function OCaml中的函数包装器/装饰器
我有一个具有以下签名的函数:Function OCaml中的函数包装器/装饰器,function,ocaml,wrapper,Function,Ocaml,Wrapper,我有一个具有以下签名的函数: val func : a -> b -> c -> d -> e -> f -> unit 有时也会引发例外。我想更改控制流,使其看起来像这样: val funcw : a -> b -> c -> d -> e -> f -> [ `Error of string | `Ok of unit ] let w1 f x = try `Ok (f x) with e -> `Error
val func : a -> b -> c -> d -> e -> f -> unit
有时也会引发例外。我想更改控制流,使其看起来像这样:
val funcw : a -> b -> c -> d -> e -> f -> [ `Error of string | `Ok of unit ]
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)
我尝试包装它的方式很难看:制作另一个函数,
funcw
,它接受相同数量的参数,对它们应用func
,并使用尝试/。但肯定有比这更好的办法。想法?您可以将f
作为包装器函数的一个参数。这更一般一点
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)
然后,func
的包装版本是(w6 func)
此包装器适用于6个参数的curried函数,如func
。您不能为所有不同数量的参数定义一个包装器(因为它们有不同的类型),但您可以为不同数量的参数定义一系列包装器,如下所示:
val funcw : a -> b -> c -> d -> e -> f -> [ `Error of string | `Ok of unit ]
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)
可能会有一个更整洁的方案,但这看起来相当不错。对不起,我意识到我有两个f
s(一个是函数,一个是类型)。更改为func
和funcw
。我宁愿避免这种解决方案,因为它消除了参数func
所采用的单一真理点。FWIW类型和值占用不同的名称空间。您可以有一个名为f的函数和一个名为f的类型。我最终在我们使用的库中找到了一个应用程序函子shim。看看是否好奇。谢谢你的帮助!