Haskell中的"依赖可选"数据

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,但其他解决方案看起来很混乱,也许这更优雅.)

  • @DanielWagner,我认为这不会起作用,不是没有改变数据类型:(对于32位平台),"Int"的最大值是几十亿,但一天有86万亿纳秒. (2认同)

dav*_*420 8

"必须不惜一切代价避免非法国家","模式匹配会很酷"是在这种情况下彼此直接冲突的优良原则.

此外,日期和时间是粗糙的人类文化结构,有许多边缘情况和不规则的角落.它们不是我们可以在类型系统中轻松编码的规则.

所以在这种情况下,我会使用不透明的数据类型,智能构造函数和智能解构器.当我们想要使用模式匹配时,总会看到模式和图案防护.

(我甚至没有讨论过相关的可选数据作为激励因素.)