Ho visto questa domanda ma non lo fa aiutami perché sto scrivendo codice funzionale (Standard ML) e le risposte sono strongmente focalizzate su OOP (l'OP si consiglia di usare il modello di facciata, di usare l'ereditarietà, ecc. - risposte che non sono rilevanti per un programmatore SML) .
In due moduli separati, in gran parte non correlati, Foo
e Bar
, ho bisogno di svolgere lo stesso compito: date funzioni equal
e equals
con le firme:
val equal: t * t -> bool
val equals: t list * t list -> bool
crea due nuove funzioni con le seguenti firme:
val equal': t * t -> t option
val equals': t list * t list -> t list option
Qui, t
rappresenta Foo.t
o Bar.t
. La soluzione naturale è utilizzare una funzione di ordine superiore:
local
fun boolToOpt (comparison: ('a * 'a) -> bool) (left, right) =
if comparison (left, right) then
SOME left
else
NONE
in
val equal' = boolToOpt equal
val equals' = boolToOpt equals
end
Devo ripetere esattamente questo snippet di codice in entrambi i moduli.
Ora, questo è un dettaglio di implementazione minimo e minuscolo e sarebbe una cattiva idea renderlo pubblicamente visibile da Foo
o Bar
. Allo stesso tempo, sembra troppo piccolo - e troppo strettamente collegato alle due funzioni equal(s)
- da includere in un modulo a sé stante. Forse in un'altra lingua, la funzionalità equals'
meriterebbe una sua classe, ad esempio ComparisonDecorator
, che sostituisce equal(s)
per darmi funzioni con il tipo di ritorno t option
, ma non è un'opzione qui.
Corro in situazioni come queste almeno una volta al giorno. Esiste un modo corretto per evitare solo copia e incolla qui?