我有一些我真的想摆脱的代码重复 -
// here's some lib code the repetitive code relies on...
module Option
let definitize opts = List.choose id opts
// here's the start of another file...
module Ast
type Expr =
| Violation of Expr
| Boolean of bool
| String of string
// here's the repetitive code...
let exprToOptViolation expr = match expr with | Violation v -> Some v | _ -> None
let exprToOptBoolean expr = match expr with | Boolean b -> Some b | _ -> None
let exprToOptStr expr = match expr with | String n -> Some n | _ -> None
let exprsToOptViolationStrs exprs = List.map exprToOptViolation exprs
let exprsToOptBools exprs = List.map exprToOptBoolean exprs
let exprsToOptStrs exprs = List.map exprToOptStr exprs
let exprsToViolationStrs exprs =
let optViolationStrs = exprsToOptViolationStrs exprs
let violationStrs = Option.definitize optViolationStrs
(optViolationStrs, violationStrs)
let exprsToBools exprs =
let optBools = exprsToOptBools exprs
let bools = Option.definitize optBools
(optBools, bools)
let exprsToStrs exprs =
let optStrs = exprsToOptStrs exprs
let strs = Option.definitize optStrs
(optStrs, strs)
如您所见,它是相同的算法重复 3 次。但是,我不知道如何概括需要传递像match expr with | destructureFn a -> Some a | _ -> None
. 有人可以帮忙吗?实际上,我的代码中有 5 次重复(并且还在增长)需要分解。
干杯!
* 结论 *
使用 desco 的答案,我已经达到了这个重构 -
let exprsToValues exprToOptValue exprs =
let optValues = List.map exprToOptValue exprs
let values = Option.definitize optValues
(optValues, values)
let exprsToViolationStrs exprs = exprsToValues (fun expr -> match expr with | Violation v -> Some v | _ -> None) exprs
let exprsToBools exprs = exprsToValues (fun expr -> match expr with | Boolean b -> Some b | _ -> None) exprs
let exprsToStrs exprs = exprsToValues (fun expr -> match expr with | String s -> Some s | _ -> None) exprs
谢谢德斯科!