2015-09-29 2 views
2

Предположим, что в C, мы имеем следующие структуры:Один данных с двумя структурами: Функциональное программирование против императивного программирования

struct MyData { 
    char key1[20]; 
    long key2; 
    ... /* some data */ 
}; 

По существу, в дополнение к некоторым данным, у нас есть два ключа: key1 и key2. Предположим, нам нужно управлять связкой объектов MyData двумя разными способами, например, быстро найти соответствующий объект на основе key1 или key2 (но не для обоих). Одним из способов удовлетворения этого требования является создание двух разных RB-деревьев (или хеш-таблиц) в соответствии с двумя ключами соответственно. В C/C++ данные не нужно дублировать, так как нам нужно только записывать указатели на объекты.

В приведенном выше гипотетическом примере ключевым моментом является то, что у нас есть куча данных с одним типом, и мы можем организовать его через две разные структуры данных, не дублируя данные на императивном языке. Мне интересно, как чистое функциональное программирование может эффективно удовлетворить это требование без дублирования данных. Чтобы сделать его более общим или сложным, две структуры данных могут быть не одного типа. Например, может быть rb-дерево, а другое может быть хэш-таблицей.

Если возможно, укажите свое решение в Haskell.

PS: Как новичок в функциональном программировании, я не мог не задаться вопросом, как достичь некоторых трюков от императивного программирования в чисто функциональном программировании. Я знаю, что иногда это не имеет никакого смысла. Если кто-то считает, что этот вопрос также бессмыслен, пожалуйста, придумайте подробные рассуждения.

Thanks

+0

Не могли бы вы использовать союз здесь, намереваясь использовать либо key1 или key2 в эта структура MyData? –

+0

Нет. Если вы используете key1 для поиска объекта, вы также можете узнать, каково соответствующее значение key2 объекта. –

+0

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

ответ

7

Это, как правило, также не является проблемой в функциональном программировании.

data MyData = MyData 
    { key1 :: ByteString 
    , key2 :: Int 
    , {- some data -} } 

Теперь мы можем построить HashMap ByteString MyData, используя key1 в качестве ключа, или Vector MyData использованием key2 в качестве индекса, или любой другой. Только указатели на клавиши будут дублироваться, а не записи или даже сами клавиши.

+0

Вы имеете в виду независимо от того, насколько сложна MyData, компилятор функционального программирования может автоматически идентифицировать объекты, содержащие одни и те же данные? –

+4

@YanZhu, no. Но если вы что-то вычислили, и придерживаетесь его в нескольких разных структурах данных, каждый из них (обычно) содержит только указатель на него. – dfeuer

+4

@YanZhu Обычно это не сделано, нет.Однако, в отличие от языков, где изменчивость является нормой, а копирование - единственная безопасная вещь, в Haskell практически никаких операций не создается копия части данных (которая ведь не может измениться!). –

4

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

Другими словами, нет никаких оснований не считать, Haskell (или любой другой современный язык) обрабатывает это, как ожидается, и так же эффективно, как С.

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