日付が存在する必要があるが、秒単位の時間部分はオプションであるDateTimeタイプについて考えてみます。時間の部分がある場合は、オプションのミリ秒の部分もある可能性があります。ミリ秒が存在する場合は、ナノ秒の部分もある可能性があります。
これに対処する方法はたくさんあります。例:
--rely on smart constructors
data DateTime = DateTime { days:: Int,
sec :: Maybe Int,
ms :: Maybe Int,
ns :: Maybe Int
}
-- list all possibilities
data DateTime = DateOnly Int
| DateWithSec Int Int
| DateWithMilliSec Int Int Int
| DateWithNanoSec Int Int Int Int
-- cascaded Maybe
data DateTime = DateTime Int (Maybe (Int, Maybe (Int, Maybe Int)))
-- cascaded data
data Nano = NoNano | Nano Int
data MilliSec = NoMilliSec | MilliSec Int Nano
data Sec = NoSec | Sec Int MilliSec
data Date = Date Int Sec
どの構成を使用しますか(もちろん、上記の例に限定されません)、そしてその理由は何ですか?
【意図】
ガイドラインとしてdate4jを使用して、Frege(http://code.google.com/p/frege/DateTime
)で日付型の可能性を探っています(Haskellの日付と時刻のライブラリは非常に複雑でjava.util.Date
壊れているため) )。私の現在のおもちゃの実装では、すべてのフィールドが必須ですが、もちろん、ユーザーを不要な精度から解放すると便利です(元の実装にはオプションのフィールドがあります)。
したがって、主な目標は次のとおりです。
- 安全性:違法な状態は絶対に避けなければなりません
- 利便性:タイプを操作するのは簡単である必要があります。たとえば、パターンマッチングはクールで、カレンダーの計算は簡単である必要があります...
それほど重要ではありません:
- パフォーマンス:もちろん、このタイプでの作業は遅すぎるべきではありませんが、通常の使用法では、最後のクロックサイクルを絞り出す必要はありません。
- メモリ:これが本当に重要な場合は、よりコンパクトなストレージ形式を簡単に導き出すことができます
- 簡潔な実装:これはライブラリであり、スムーズにするために必要なすべてのコードを追加したいと思います。
とは言うものの、これはすべて非常に暫定的なものであり、あまり深刻に受け止めるべきではありません。