Может ли кто-нибудь указать мне на примеры многопараметрического (объектно-функционального) программирования в F #?

Может ли кто-нибудь указать мне на примеры многопараметрического (объектно-функционального) программирования в F #?

Я специально ищу примеры, которые объединяют OO и функциональное программирование. Было много разговоров о том, как F # является гибридным языком, но я не смог найти примеры, которые демонстрируют пример программирования с несколькими группами.

Спасибо

Ответ 1

Существует два способа комбинирования функциональной и объектно-ориентированной парадигмы. В какой-то степени они независимы, и вы можете написать неизменяемый (функциональный) код, который структурирован с использованием типов (написанных как объекты F #). Пример F # типа Client, написанный следующим образом:

// Functional 'Client' class
type Client(name, income) =
  // Memebers are immutable
  member x.Name = name
  member x.Income = income

  // Returns a new instance 
  member x.WithIncome(ninc) =
    new Client(name, ninc)
  member x.Report() =
    printfn "%s %d" name income

Обратите внимание, что метод WithIncome (который "изменяет" доход клиента) фактически не вносит никаких изменений - он следует функциональному стилю и создает новый, обновленный клиент и возвращает его в качестве результата.

С другой стороны, в F # вы также можете написать объектно-ориентированный код, который имеет изменяемые общедоступные свойства, но использует некоторую неизменяемую структуру данных под обложкой. Это может быть полезно, когда у вас есть хороший функциональный код, и вы хотите показать его программистам на С# традиционным (императивным/объектно-ориентированным) способом:

type ClientList() =
  // The list itself is immutable, but the private
  // field of the ClientList type can change
  let mutable clients = []
  // Imperative object-oriented method
  member x.Add(name, income) =
    clients <- (new Client(name, income))::clients
  // Purely functional - filtering of clients
  member x.Filter f = 
    clients |> List.filter f

(Пример взят из исходного кода главы 9 моей книги. Есть еще несколько примеров неизменяемого объектно-ориентированного кода, например, в параллельном моделировании в главе 14).

Ответ 2

Я сделал небольшой (600 строк) клон Tetris с F #, который объектно ориентирован с использованием XNA. Код старый (использует #light) и не самый красивый код, который вы когда-либо видели, но вызывающе представляете собой сочетание ООП и функциональности. Он состоит из десяти классов. Я не думаю, что передаю функции первого класса, но это хороший пример функциональной мощности F # в программирование небольшого.

  • MyGame - Наследует основной игровой класс XNA и является точкой входа в программы.
  • Board - отслеживает фрагменты, которые больше не перемещаются, а горизонтальная линия завершается.
  • UI - Пользовательский интерфейс имеет только два состояния (воспроизведение и главное меню), обрабатываемых bool stateMenu
  • Tetris - обрабатывает состояние игры. Игра над и кусочком столкновения.
  • Piece - Определяет различные формы тетриса и их движение и рисунок.
  • Player - обрабатывает ввод пользователя.
  • Shape - базовый графический объект, который сопоставляется с примитивным.
  • Primative - Обертывает примитивный тип Вершины.

Я сделал грубую диаграмму классов, чтобы помочь. Если у вас есть какие-либо вопросы по этому поводу, не стесняйтесь спрашивать в разделе комментариев.

alt text

Ответ 3

Самый мощный опыт, с которым я смешал OO (в частности, мутацию) и функциональное программирование, - это достижение повышения производительности за счет использования изменяемых структур данных внутри компании, пользующихся всеми преимуществами неизменности внешних пользователей. Отличным примером является реализация, которую я написал об алгоритме, который дает лексикографические перестановки, вы можете найти здесь. Используемый мною алгоритм является обязательным в его ядре (повторяющиеся шаги мутации массива), которые пострадали бы, если бы они были реализованы с использованием функциональной структуры данных. Принимая входной массив, сначала создавая его только для чтения, чтобы вход не был поврежден, а затем он выдавал только копии для чтения в выражении последовательности после выполнения шагов мутации алгоритма, мы получаем прекрасный баланс между ОО и функциональными методами. Связанный ответ ссылается на исходную реализацию С++, а также на тесты других чисто функциональных ответов на реализацию. Производительность моей смешанной OO/функциональной реализации отстает от превосходной производительности решения OO С++ и чистого функционального решения F #.

Эта стратегия использования OO/изменяемого состояния внутри, сохраняя чистое внешнее значение для вызывающего, используется во всей библиотеке F #, особенно с прямым использованием IEnumerators в модуле Seq.

Другой пример может быть найден путем сравнения memoization с использованием изменяемой реализации Dictionary по сравнению с неизменяемой реализацией карты, которую Дон Симе исследует здесь. Непрерывная реализация Словаря выполняется быстрее, но не менее чиста в использовании, чем реализация карты.

В заключение я думаю, что использование изменчивого OO в F # является самым мощным для разработчиков библиотек, стремящихся повысить производительность, сохраняя при этом все чисто функциональные для пользователей библиотеки.

Ответ 4

Я не знаю F #, но я могу показать вам пример точной языковой механики, которую вы ищете в Scala. Игнорируйте его, если это не поможет.

class Summation {

    def sum(aLow : Int, aHigh : Int) = {
        (aLow to aHigh).foldLeft(0) { (result, number) => result + number }
    }

}

object Sample {

    def main(args : Array[String]) {
        println(new Summation sum(1, 10))
    }

}

Я старался держать его очень простым. Обратите внимание, что мы объявляем класс для суммирования диапазона, но реализация используется с функциональным стилем. Таким образом, мы можем абстрагировать парадигму, которую мы использовали для реализации фрагмента кода.

Ответ 5

Я не знаю о F #, но большинство программ, написанных в Scala, носят функционально-функциональный характер.

Scala Компилятор, вероятно, самый большой и современный пример функционально-функционального программного обеспечения. Другие примечательные примеры включают Akka, Lift, SBT, Kestrel и т.д. (Googling будет находят вас более объектно-функциональными Scala примерами.)