2014-10-17 2 views
1

Проблема, с которой я часто сталкиваюсь при разработке типа данных в Haskell, заключается в том, чтобы использовать тип суммы или записи Maybe Eithers.Sum Type Vs Record of Maybes

Простым примером может быть моделирование операции FX, spot или forward, где единственной разницей является наличие или отсутствие даты «зрелости» (один из способов - использовать тип суммы, явно указывать, является ли это пятном или вперед.

data Amount = Amount { amount :: Double, currency :: String } 
data Fx = Spot { tranDate :: Day, soldAmount :: Amount, boughtAmount :: Amount } 
     | Forward { tranDate :: Day, paidAmount :: Amount, boughtAmount :: Amount , maturity :: Day} 

Другим способом было бы просто иметь maturity как `` Может быть»

data Fx = Fx { tranDate :: Day 
      , soldAmount :: Amount 
      , boughtAmount :: Amount 
      , maturity (Maybe Day) 
      } 

или что-нибудь еще

+1

Я не уверен, в какой области вы здесь говорите. Если 'Spot' и' Forward' - довольно четкое поведение, требующее одинаковых данных, я бы пошел с 'Spot | Forward' ADT; если они очень похожи, и просто добавляется немного информации/сложности, я бы пошел с решением 'Maybe Day'. – luqui

ответ

4

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

Но вместо того, чтобы поместить Maybe внутри записи, я бы определил оберточную запись, например:

data Spot = Spot 
    { tranDate :: Day 
    , soldAmount :: Amount 
    , boughtAmount :: Amount 
    } 

data Forward = Forward 
    { spot :: Spot 
    , maturity :: Day 
    } 

и возможно даже HasSpot класс типов, а также, что оба Spot и Forward бы реализовать.

Но теперь трудно разместить значения Spot и Forward в одной коллекции. Возможно, в этом случае можно использовать такой тип, как (Maybe Day, Spot).

Подход «обернуть» этого ответа не очень хорошо обобщается на более чем одно необязательное поле.

1

Второй пример не связывает хорошо. Вы должны проверить maturity, чтобы отличить форвард и место. Тип суммы связывается намного лучше.

+0

Тип суммы менее читабельный IMHO, из-за повторяющихся полей. – danidiaz

+0

Я думаю, что ваш ответ сочетает в себе лучшее из того и другого. –