Lan*_*dei 12 haskell algebraic-data-types
考虑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
Run Code Online (Sandbox Code Playgroud)
你会使用哪种结构(当然不限于上面的例子),为什么?
[意向]
我正在探索Frege(http://code.google.com/p/frege/)中日期类型的可能性,使用date4j DateTime
作为指导线(因为Haskell的日期和时间lib太复杂了,而且java.util.Date
太破碎了).在我目前的玩具实现中,所有字段都是强制性的,但当然,将用户从不必要的精度中解放出来会很好(并且原始实现具有可选字段).
所以主要目标是:
不那么重要的是:
也就是说,所有这些都是非常试探性的,不应该过于严肃.
huo*_*uon 10
(这不是一个答案,但是评论太长了,这里会更清楚.)
还有另一种方法可以处理它:只有一种DateTime
类型可以存储所有字段以及表示精度的参数,例如
data Precision = Days | Seconds | Milliseconds | Nanoseconds deriving (Ord, Eq {- etc -})
data DateTime = DateTime { prec :: Precision,
days :: Int,
sec :: Int,
ms :: Int,
ns :: Int }
Run Code Online (Sandbox Code Playgroud)
并使用设置未使用参数的智能构造函数0
.如果你有dateDifference
或者其他什么,你可以传播精度(Ord
实例会使这个整洁).
(我不知道这有多好/ Haskell-y,但其他解决方案看起来很混乱,也许这更优雅.)
"必须不惜一切代价避免非法国家","模式匹配会很酷"是在这种情况下彼此直接冲突的优良原则.
此外,日期和时间是粗糙的人类文化结构,有许多边缘情况和不规则的角落.它们不是我们可以在类型系统中轻松编码的规则.
所以在这种情况下,我会使用不透明的数据类型,智能构造函数和智能解构器.当我们想要使用模式匹配时,总会看到模式和图案防护.
(我甚至没有讨论过相关的可选数据作为激励因素.)
归档时间: |
|
查看次数: |
540 次 |
最近记录: |