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?