2012-10-29 23 views
5

Jeodezik hesaplamalar için bir kitaplık yazıyorum. Dahil etmek istediğim bir şey, ızgara projeksiyonları için bir türdür (örn. Ordnance Survey National Grid) ve bu ızgaralar üzerindeki noktaları ("eastings" ve "northings" ile belirtilir). Bir ızgara, Dünya'ya ve bir takım geometrik parametrelere bağlayan bir başlangıç ​​noktasıyla belirtilir. Uygulama programcısı bu parametreleri kullanarak birçok rasgele ızgara oluşturabilir. Altta yatan farklı projeksiyonlara dayanan bir dizi ızgara da olacak.Uyumsuz değerleri ayırmak için türleri nasıl kullanırım

Açıkçası, grid noktaları (örn. Mesafe, yatak vb.), üzerinde hesaplamalar yapmak istiyorum ama aynı zamanda bir uygulama programcısının iki arasındaki mesafeyi sormasını engellemek için Haskell tipi sistemi kullanmak istiyorum. Farklı ızgaralarda noktalar. ST monadının hatları boyunca bir tip parametresi kullanan bir Reader Monad'in çalışıp çalışmayacağını merak ettim, fakat uygulama programcısının bu pozisyon değerlerini monad dışında saklamasını istiyorum, ST'nin ise STDS'nin sızmasını önlemekle ilgili olduğunu düşünüyorum. runST.

Altta yatan elipsoidler üzerinde jeodezik konumlarla (enlem & boylam) benzer bir sorunum var. Ancak grid versiyonunun açıklanması muhtemelen daha kolaydır, çünkü bu sorunun odağı jeodetikler yerine tip sistemidir.

GADT'leri ve varoluşsal türlerini okudum, ancak bunu nasıl yapacağımı göremiyorum.

+0

Bu tür bir aritmetik ile yapmanın bir yolu olabilir: http://www.haskell.org/haskellwiki/Type_arithmetic – Wes

+0

"ama aynı zamanda bir uygulama programcısının sormasını engellemek için Haskell tipi sistemi kullanmak istiyorum Farklı ızgaralardaki iki nokta arasındaki mesafe "- neden bu? Noktalar farklı ızgaralarda tanımlanabilir ve hala aynı _physical_ konumunu temsil edebilir, neden bu noktaların arasındaki mesafeyi hesaplamak istemezsiniz? – leftaroundabout

+0

@leftaroundabout: evet, ancak bu bir koordinat dönüşümü ve daha karmaşık hesaplamalar gerektirir. Ayrıca bazı durumlarda basit düzlemsel hesaplama Doğru Şey'dir (örneğin radarlarla uğraşırken). –

cevap

2

Sen geldikleri grid koordinatları işaretlemek için izin vermek için iki GHC uzantıları kullanabilirsiniz: (., 7.4+ uzantıları ghc çalışmak alt hiçbir şeyden emin)

{-# LANGUAGE DataKinds, KindSignatures #-} 

data CoordinateType = Geodetic | OSNG -- etc. 

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

zeroZero :: Coordinate Geodetic 
zeroZero = Coord 0 0 

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

Şimdi distance zeroZero (Coord 1 2 :: Coordinate OSNG) bir tür hata veriyor: Sonra onu gerektiren fonksiyonlar grid fantom parametresinin eşitliği zorunlu kılabilir.

+0

Bunu doğru olarak anlarsam, yalnızca kodlanmış CoordinateType değerleri listesi için çalışır (aslında daha önce de olsa tip sınıflarını kullanarak yaptım). Ben "veri CoordType = Grid Double Double" gibi bir şey söylemek istiyorum ki "foo = Izgara 3 4; bar = Grid 2 4.2", "foo" içindeki koordinatları tür düzeyinde "bar" koordinatlarından ayırmamı sağlar. –

+0

@PaulJohnson, sabit kodlanmış bir değerler listesiyle sınırlı değilsiniz, çünkü (şimdi GHC 7 gerektirir).6) tip seviyesinde dizeleri ve doğalları kullanabilirsiniz ("tanıtılan edebi ürünler"). Verilerle ilgili dokümantasyon -> türden tanıtım [burada] (http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/promotion.html), bunlardan herhangi birinin yardımcı olup olmadığını görebilirsiniz. – huon

+0

Ama onlar da değişmez olmalı: Ben (görebildiğim kadarıyla) bir dosyadan bir dize okuyamıyorum ve bunu bir türe teşvik ediyorum. –

İlgili konular