In OOP è buona norma parlare alle interfacce non alle implementazioni. Così, ad esempio, si scrive qualcosa di simile (da Seq
intendo scala.collection.immutable.Seq
:)):Mancanza corrispondenza impedenza funzionale oggetto
// talk to the interface - good OOP practice
doSomething[A](xs: Seq[A]) = ???
non
qualcosa di simile al seguente:
// talk to the implementation - bad OOP practice
doSomething[A](xs: List[A]) = ???
Tuttavia, in puro linguaggi di programmazione funzionali come Haskell , non si ha il polimorfismo del sottotipo e si usa, invece, il polimorfismo ad hoc attraverso classi di tipi. Quindi, ad esempio, hai il tipo di dati dell'elenco e un'istanza monadica per l'elenco. Non devi preoccuparti di usare un'interfaccia/classe astratta perché non hai un tale concetto.
Nei linguaggi ibridi, come Scala, si hanno entrambe le classi di tipi (attraverso un modello, in realtà, e non cittadini di prima classe come in Haskell, ma divagando) e il sottotipo polimorfismo. In scalaz
, cats
e così via si hanno istanze monadiche per tipi concreti, non per quelli astratti, ovviamente.
Infine la domanda: dato questo ibridismo di Scala si fa comunque rispettare la regola OOP di parlare con interfacce o semplicemente parlare con tipi concreti per approfittare di funtori, monadi e così via direttamente senza dover convertire in cemento scrivi ogni volta che devi usarli? In altre parole, è ancora valido in Scala parlare con le interfacce anche se si desidera abbracciare FP anziché OOP? In caso contrario, che cosa succede se hai scelto di utilizzare List
e, in seguito, ti sei reso conto che una Vector
sarebbe stata una scelta migliore?
P.S .: Nei miei esempi ho utilizzato un metodo semplice, ma lo stesso ragionamento si applica ai tipi definiti dall'utente. Es .:
C'è anche .. 'def doQualcosa [A, M [X] <: Seq [X]] (xs: M [A]) = ???' –
Questa domanda potrebbe essere più adatta per [Programmatori SE] (http://programmers.stackexchange.com/). I motivi principali per parlare con le interfacce è 1) potresti voler sostituire un'implementazione con un'altra e 2) in modo da poter isolare i tuoi tipi l'uno dall'altro quando si scrivono i test delle unità. Questi problemi non si applicano ai tipi "primitivi", come ints o string - non c'è interfaccia per 'int' o' string'. – dcastro
Ritengo che la maggior parte delle monadi siano primitive che ti aiutano a incollare il tuo codice. Pertanto, non c'è bisogno di interfacce. – dcastro