私は本当に取り除きたいコードの繰り返しがあります-
// 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
ありがとうdesco!