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

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

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

Спасибо

Ответы [ 5 ]

9 голосов
/ 07 ноября 2010

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

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

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

alt text

6 голосов
/ 07 ноября 2010

Существует два способа сочетания функциональной и объектно-ориентированной парадигмы.В некоторой степени они независимы, и вы можете написать неизменный (функциональный) код, структурированный с использованием типов (написанных как объекты 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 # вы также можете написать объектно-ориентированный код, который имеет изменяемые открытые свойства, но использует некоторые неизменяемыеструктура данных под крышкой.Это может быть полезно, когда у вас есть хороший функциональный код и вы хотите показать его программистам на C # традиционным (императивным / объектно-ориентированным) способом:

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).

4 голосов
/ 11 ноября 2010

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

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

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

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

3 голосов
/ 06 ноября 2010

Я не знаю 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))
    }

}

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

2 голосов
/ 07 ноября 2010

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

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

...