2012-04-09 4 views
4

Supose мы имеем очень простую модель:Внедрение простой бизнес-модели в Haskell

Station имеет по крайней мере один Train
Train имеет по крайней мере два Station сек

модель должна позволить, чтобы проверить, какие станции любой посещений поездов и проверить, какие поезда посещают конкретную станцию.

Как смоделировать его в Haskell?


Я новичок в Haskell, поэтому, пожалуйста, поправьте меня: как только объект создан, вы не можете изменить его - вы можете сделать только новый объект на основе этого одного (~ неизменности). Я прав? Если это так, Мне нужно будет создать много временных переменных с полуинициализированными объектами (во время десериализации или даже в модульных тестах).

В принципе, мне нужен пример моделирования классов домена в Haskell - после прочтения «Учите вас haskell ..». Я до сих пор не знаю, как использовать этот язык.

ответ

4

Вот наивный подход:

data Station = Station Train [Train] 
data Train = Train Station Station [Station] 

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

grandCentral = Station regional [national] 
bestWestern = Station regional [national] 
regional = Train grandCentral bestWestern [] 
national = Train grandCentral bestWestern [] 

Однако, существует много недостатков этого подхода; соблюдение циклов в куче невозможно из чистого подмножества Haskell, поэтому обновление или использование этих данных сложно. Обычное обходное решение - явно указать ваши указатели.

type TrainMap = Map TrainId Train 
type StationMap = Map StationId Station 
type TrainId = Int -- use newtype for more compiler checks at 
type StationId = Int -- the cost of more programmer annoyance 
data Train = Train StationId StationId [StationId] 
data Station = Station TrainId [TrainId] 
+0

Для 'Station' вы можете использовать' Station (NonEmpty TrainId) ', но, к сожалению, это не помогает для поездов. – Landei

+0

@ Даниэль - спасибо за ваш ответ. Некоторые вопросы относительно вашего кода: во-первых, можете ли вы сделать forward-declarations ** объектам ** в Haskell? во-вторых, когда вы пишете 'region = Train grandCentral' - это' grandCentral' ** ссылка **, ** указатель ** или ** копия ** объекта? Ну, как я уже сказал, я новичок Haskell, но если нет правильного способа моделирования реальной логики/отношений, то как мы должны использовать этот язык? Мне нравится идея с картой. – emesx

+1

@elmes Нет форвардных или обратных объявлений. Есть только декларации. Когда вы пишете 'region = Train grandCentral', реализация GHC создает thunk, который при оценке генерирует тэг' Train' и указатель на 'grandCentral' thunk в любом состоянии оценки' grandCentral' бывает в то время , Я не уверен, что понимаю гипотезу вашего последнего вопроса, а именно, что нет надлежащего способа моделирования реальной логики/отношений; можете ли вы сказать, что хотите более точно и в каком смысле это невозможно? –

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