如何使用单位定义值集合?

时间:2014-10-12 01:16:29

标签: haskell

我想定义一组数据数组并将每个数据与单元相关联。例如,集合中的一个成员可能是Vector Float,我以某种方式将单位米关联起来。另一个成员可能是Vector Int,我将单位计数关联起来。另一个可能是Vector Double,我将单位厘米关联起来。我的用例是,对于集合的每个成员,我想:

  1. 显示数据的精确度(即Int vs Float vs Double vs Int64
  2. 根据精确度显示数值(例如[1.0,3.0,4.0]或[1,3,4])。
  3. 显示值的重要性,包括单位(即长度计,计数,长度厘米)。
  4. 每个数据数组都是从定义值数组,精度和单位的文件中读取的,因此编译时都不能使用这些数据。

    如何定义此类集合的类型,例如IntMap?我可以使用现有的单位相关图书馆这样做,还是我需要自己动手?我愿意使用完成工作所需的任何GHC扩展(例如GADT)。

    我在尝试制定解决方案时遇到了以下问题。

    • Vector FloatVector DoubleVector Int都是不同的类型,所以我不能将它们放入没有existential quantification的同一个集合中,例如{{3}的答案}}。但是,如果我使用Num类作为约束使用存在量化,我会删除精度信息。
    • dimensional this question中的单位属于类型级别,因此数量为Length的数组不能与数量为Time的数组位于同一集合中。同样,这可以通过存在量化来解决,并且再次破坏所需的信息。其他单位套餐我也找到了类型级别的处理单位。

    一种可能的解决方案是将单位和精度信息从类型级别和数据级别中取出:

    data Quantity = Length LengthUnit
                  | Time TimeUnit
                  | Count
                  | Angle AngleUnit
                  etc
    
    data TimeUnit = Sec | MSec | Hour | Day
    data AngleUnit = Deg | Rad | etc
    data LengthUnit = Meter | Centimeter | Mile
    etc
    
    data Precision = Int | Float | Double
    
    data DataArray quant prec = forall e . Num e => DataArray Quantity Precision (Vector e)
    

    (这个简单的单位系统可以通过添加前缀,转换因子等来改进,就像单位包通常那样。上面的例子仅用于说明目的。)

    这也带来了许多问题。首先,很容易定义DataArray具有不一致类型的DataArray Angle Int (Vector Float),例如{{1}}。在实施全新的单位系统和冗余地定义数据的精确度方面,它还有重新发明轮子的气味。

    我觉得我过于复杂,应该很简单。什么是实现我的使用目标的类型策略?

0 个答案:

没有答案