如何使用类型分隔不兼容的值

时间:2012-10-29 02:10:43

标签: haskell

我正在为大地测量计算编写一个库。我想要包括的一件事是网格投影的类型(例如军械测量国家网格)和那些网格上的点(由“东方”和“北方”指定)。网格由原点指定,该原点将其与地球和一堆几何参数联系起来。应用程序员可以使用这些参数创建许多任意网格。根据不同的潜在预测,还会有一系列类型的网格。

显然我希望能够对网格点进行计算(例如距离,方位等), 但与此同时,我想使用Haskell类型系统来阻止应用程序员询问不同网格上两点之间的距离。我想知道使用ST monad行的类型参数的Reader Monad是否可以工作,但是我希望应用程序员能够将这些位置值存储在monad之外,而ST则是关于防止STRef泄漏runST。

我在底层椭球上也遇到了与大地位置(纬度和经度)类似的问题。但是网格版本可能更容易解释,因为这个问题的焦点是类型系统而不是大地测量。

我已经读过GADT和存在类型,但我看不出怎么做。

1 个答案:

答案 0 :(得分:2)

您可以使用两个GHC扩展来标记它们来自网格的坐标:

{-# LANGUAGE DataKinds, KindSignatures #-}

data CoordinateType = Geodetic | OSNG -- etc.

data Coordinate (grid :: CoordinateType) = Coord Int Int

zeroZero :: Coordinate Geodetic
zeroZero = Coord 0 0

(扩展适用于GHC 7.4+,不确定任何更低的内容。)

然后,任何需要它的函数都可以强制grid幻像参数的相等性:

distance :: Coordinate grid -> Coordinate grid -> Float
distance p q = undefined

现在distance zeroZero (Coord 1 2 :: Coordinate OSNG)会出现类型错误。