В ООП это хорошая практика говорить интерфейсам не к реализациям. Так, например, вы пишете что-то вроде этого (по Seq
я имею в виду scala.collection.immutable.Seq
:)):Несимение объектно-функционального импеданса
// talk to the interface - good OOP practice
doSomething[A](xs: Seq[A]) = ???
не что-то вроде следующего:
// talk to the implementation - bad OOP practice
doSomething[A](xs: List[A]) = ???
Однако в чистых функциональных языков программирования, таких как Haskell , у вас нет полиморфизма подтипа и вместо этого используйте ad hoc-полиморфизм через классы классов. Так, например, у вас есть тип данных списка и монадический экземпляр для списка. Вам не нужно беспокоиться об использовании интерфейса/абстрактного класса, потому что у вас нет такой концепции.
В гибридных языках, таких как Scala, у вас есть классы типа (через шаблон, фактически, а не первоклассные граждане, как в Haskell, но я отвлекаюсь) и полиморфизм подтипов. В scalaz
, cats
и т. Д. У вас есть монадические экземпляры для конкретных типов, а не абстрактные, конечно.
Наконец вопрос: при таком гибридность от Scala вы до сих пор уважают правила ООП говорить с интерфейсами или просто поговорить с конкретными типами, чтобы воспользоваться функторы, монады и так далее непосредственно без необходимости конвертировать в бетон типа, когда вам нужно их использовать? По-другому, в Скала по-прежнему хорошая практика разговаривать с интерфейсами, даже если вы хотите использовать FP вместо OOP? Если нет, что делать, если вы решили использовать List
, и, позже, вы поняли, что выбор Vector
был бы лучшим выбором?
P.S .: В моих примерах я использовал простой метод, но те же рассуждения применимы к пользовательским типам. Например:
case class Foo(bars: Seq[Bar], ...)
Существует также .. 'def doSomething [A, M [X] <: Seq [X]] (xs: M [A]) = ???' –
Этот вопрос может быть лучше подходит для [Programmers SE] (http://programmers.stackexchange.com/). Основными причинами разговора с интерфейсами являются: 1) вы можете заменить реализацию другим и 2), чтобы вы могли изолировать свои типы друг от друга при написании модульных тестов. Эти проблемы не относятся к «примитивным» типам, таким как ints или string, для интерфейса 'int' или' string' нет интерфейса. – dcastro
Я считаю, что большинство монадов являются примитивами, которые помогают склеить ваш код вместе. Поэтому нет необходимости в интерфейсах. – dcastro