2013-06-13 2 views
7

мой вопрос относится к способу работы с наследованием функциональным способом в F #. Чтобы описать это немного, я приведу простой пример. Предположим, мы хотим смоделировать мир, состоящий из различных видов животных. Каждый вид животных имеет некоторые атрибуты с другими видами (например, имя, размер и т. Д.). Кроме того, у каждого вида могут быть другие, которые не разделяются другими (например, количество детей имеет отношение к собакам и кошкам, но не для пауков, например). Кроме того, могут быть методы или функции, связанные с каждым видом животных, которые могут или не могут быть одинаковыми для двух видов животных, то есть существует реализация по умолчанию, которая может быть чрезмерной для определенного вида. Каждый вид животных может иметь метод (ы), который определен только для такого рода.F # и моделирование наследования

Теперь, в мире ООП, это, вероятно, приведет к абстрактному классу, имеющему общие атрибуты и абстрактные методы, за которыми следуют классы, полученные для каждого вида животных. Я не уверен, как функционально определить модель домена в F #. Здесь: Which to use , abstract class or interface in F#? утверждает, что «идиоматический код F # использует разные точки расширяемости, чем C# (например, использование функции/интерфейса в качестве аргумента), поэтому вам не нужны абстрактные классы».

Если это способ, который должен быть принят, можно ли предоставить некоторый элементарный пример этого?

Что касается моего дальнейшего размышления об этом, я полагаю, что атрибуты должны быть инкапсулированы в какую-то структуру. Тогда большинство идиоматической структуры в этом отношении в F # является записью. Означает ли это, что должна быть родительская запись, которая должна быть включена в другие записи, соответствующие конкретным «детям», т. Е. Композиции вместо наследования. Это, однако, кажется мне обходным путем, которое не является ни идиоматическим, ни особенно элегантным.

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

Модели, похожие на упомянутые выше, довольно часто встречаются на мой взгляд, поскольку они неявно включены в большинство корпоративных приложений. Таким образом, есть ли какое-либо предложение о том, как это можно обрабатывать функциональным способом (например, способом, предложенным по ссылке выше или любым другим предложением)? Или мы скажем, что это не домен, который можно легко смоделировать с использованием функционального подхода?

спасибо.

ответ

9

Ваше описание примера уже предполагает объектно-ориентированную модель программирования. Вы описываете проблему в объектно-ориентированных терминах, таких как переопределение и методы, определенные для определенных типов животных. Это затрудняет предоставление вам разумного альтернативного функционального представления, потому что ваш вопрос уже предполагает объектно-ориентированные понятия в ответе.

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

Во-вторых, если вы объяснили свою проблему по-другому, то может быть прекрасно реализовано функциональное представление с использованием дискриминированных объединений. Например:

type MammalKind = Cat | Dog 
type MammalInfo = { Legs : int; Children : int } 

type Animal = 
    | Mammal of MammalKind * MammalInfo 
    | Spider of (...) 

Идея заключается в том, чтобы структурировать тип так, что различные виды животных (которые можно обрабатывать по-другому), имеют свой собственный тип.Например, вы можете написать функцию, которая принимает MammalInfo и выполняет некоторые вычисления, которые имеют смысл только для собак и кошек (но не для пауков). Но, как я упоминал ранее, ваше описание проблемы по своей сути объектно-ориентированное, поэтому было бы трудно понять, как это будет сделано.

+0

Хороший вопрос, отличный ответ! – mydogisbox

+0

Ответ Томаса Петричека очень хороший. Я также рекомендовал бы следующий ответ Нормана Рэмси: http://stackoverflow.com/a/2079678/631115. – Shredderroy

+0

Томас, спасибо за пример. Это хорошо и просто. Что касается описания, которое я дал, я попытался четко различить описание и возможную реализацию (абстрактный класс). Интересно, являются ли общие функции (например, функция, возвращающая название животного каким-то причудливым образом - для всех животных - или для некоторых детей - для всех млекопитающих) должны быть частью определенных типов (AnimalInfo - которая еще была создана - и MammalInfo) в качестве своих членов или объявить их свободно (не назначенными). Я также считаю, что это более общий вопрос, не связанный исключительно с типом. – user2039784

Смежные вопросы