日付が存在する必要があるDateTime型を考えてみましょう。ただし、秒単位の時間はオプションです。時間部分がある場合は、オプションのミリ秒部分もあります。ミリ秒がある場合は、ナノ秒の部分もあります。これに対処するための多くの方法がありますHaskellの "Dependent optional"データ
、例えば:
--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
構築物はあなたが(もちろん上記の例に限定されない)を使用するでしょう、そして、なぜ?
[意図]
私は、フレーゲ(http://code.google.com/p/frege/)の日付タイプの可能性を模索しdate4jのDateTime
ガイドラインとしてを使用して(Haskellの日付と時刻のlibがあまりにも複雑であるとして、そしてjava.util.Date
よあまりにも壊れた)。私の現在のおもちゃの実装では、すべてのフィールドは必須ですが、もちろん、望ましくない精度からユーザーを解放するのが良いでしょう(元の実装にはオプションフィールドがあります)。
だから、主な目標は以下のとおりです。
- 安全性:不正な状態はすべてのコスト
- 都合の良い時に避けなければならない。例えば、タイプで動作するように簡単にする必要がありますパターンマッチングは、クールになる、カレンダーの計算が簡単なはず...
それほど重要ではないが、次のとおりです。
- パフォーマンス:もちろんタイプでの作業が遅すぎることが、典型的なのためにはなりませんそれは最後のクロックサイクルをsqeezeする必要はありません。
- メモリ:これが本当に重要な場合は、よりコンパクトなストレージフォーマットを導出するのが簡単です
- 簡潔な実装:ライブラリです。物事をスムーズにするために必要なすべてのコードを追加する意思がある
しかし、これはすべて非常に暫定的なものであり、あまり深刻ではありません。
あなたの要件について詳しく知りませんが、これはわかりません。それは、型、性能、空間の考慮事項(迂回数、フィールド展開の機会など)を定義する予定の関数を含む多くのものに依存する可能性があります。 – hammar
もう一つのオプションは、単純なコンストラクタ 'DateTime = DateTime [Int ] 'を呼び出すと、' mkDateTimeWithSec :: [Int] - > DateTime'、 'isDateTimeWithSec :: DateTime - > Bool'、' getSeconds :: DateTime 'のような関数を介して、 - > Maybe Int'などパターンマッチングを使用することはできません(ガードに置き換えてアクセサー関数を使用するだけで恐ろしいことではないかもしれませんが)すべてをチェックできるので、ユーザーが違法な状態を作成することを明示的に禁止します(例えば、負の値をチェックすることができます)。 –
不特定のデータがデフォルトではなくオプションであるという元の主張は、非常に工夫された型になります - それを操作する関数を書くのは面倒です。 Just nanosecondsとNothing秒の値のようなジャンクを持つこともできます。私はタックを変え、不特定の時間値のためのデフォルト値0が理論的にも実践的にも有害であるかどうかを考え出します。 –