2013-04-04 16 views
6

Haskell'de bir geometri kütüphanesi oluşturuyorum. Onu serbest bırakmak niyetinde değilim, bu sadece benim dil bilgimi geliştirmek için kullanıyorum bir proje. Tipler ve GADT'ler

I referans çerçevesi Vector çerçevenin Kalkış ve çerçevenin dönüşü temsil eder bir açı, "mutlak hem de tanımlanan wrt işaret aşağıdaki tanım

data Local a where 
    MkLocal :: (Vectorise a) => ReferenceFrame -> a -> Local a 

ile, bir Local veri türü vardır "referans çerçevesi (hey, bu gerçek dünya değil!). Bir Vectorise geometrisi, Vector listesine dönüştürülebilir bir dönüşüme sahip olan bir geometridir.

instance Functor Local where 
    fmap f geom = localise (frame geom) (f $ local geom) 

ama derleyici tanımındaki lokalize kullanımı için Vectorisable hiçbir örnek yoktur şikayet:

O şöyle Yerel Functor örneğidir olabileceğini aklıma geldi. Sayısız GHC uzantısından birini kullanarak bu sınırlamanın etrafında bir yolu var mı?

DÜZENLEME: Açıklamalarda istediği gibi burada türlerinden bazıları fmap tip (a -> b) -> f a -> f b çünkü hata,

mantıklı
No instance for (Vectorise b) 
    arising from a use of `localise' 
In the expression: 
    localise (frame geom) (f $ local geom) 
In an equation for `fmap': 
    fmap f lgeom = localise (frame geom) (f $ local geom)) 
In the instance declaration for `Functor Local' 

olduğunu

local :: Local a -> a 
frame :: Local a -> ReferenceFrame 
localise :: (Vectorise a) => ReferenceFrame -> a -> Local a 

kullandı. a'un Vectorise'un bir örneği olması gerektiğine karar verebilir, ancak'un, bir şekilde başka bir yazım tablosunu tanımlamaksızın f kısıtlanmış dönüş türüne sahip olması gerektiğini belirleyebildiğimi belirtmedikçe, bunun nasıl olacağını tahmin edebilirdim Zaten 'un zaten hesaba uyduğu (ya da bir şekilde, bu şekilde sınıfları kısıtlamanın neden bu tür çıkarımların neden bir şekilde kırılabileceğini açıklayabiliyorsa).

ps. Ayrıca ben local ve framefmap

+1

Lütfen bize 'localise', 'local' ve' frame' türlerini ve aldığınız hata iletisini gösterin. Benim tahminim, "Yerel" için "Vectorise" örneğini kaçırıyor olmanızdır. –

+0

Bitti. Örnek bildirimi eklemeyi denedim, ancak yardımcı olmadı. Bu 'f', 'Yerel' a değil, görebildiğim kadarıyla 'Vectorise' olarak bildirmem gereken bir dönüş türü. – ovangle

cevap

13

sorun tanımına ters ters localise tip Vectorise a => a olması ikinci argüman gerektirmesi olan bir yazım hatası yukarı sabit, ancak f uyguladığınızda (tip a -> b sahip olan) local (Vectorise a => a türünde) sonucu, sonuç değerinin Vectorise örneğidir türünde bir güvencesi yoktur. Gerçekten istediğiniz şey, yalnızca Vectorise kısıtlamasına sahip türlerde çalışan bir Functor analogudur. Yakın zamana kadar bu tip sınıfları tanımlamak mümkün değildi. Bu iyi bilinen bir sorundur ve neden Data.Set'un Functor veya Monad örneğine sahip olmasının nedeni. Ancak, son ConstraintKinds GHC uzantısı, "kısıtlı functors" ile nihayet mümkün olmuştur: Daha fazla yaklaşık ConstraintKindshere ve here okuyabilir

{-# LANGUAGE GADTs, ConstraintKinds, TypeFamilies #-} 
module Test 
     where 

import GHC.Exts (Constraint) 

data ReferenceFrame = ReferenceFrame 

class Vectorise a where 
    ignored :: a 

data Local a where 
    MkLocal :: ReferenceFrame -> a -> Local a 

local :: Vectorise a => Local a -> a 
local = undefined 

frame :: Local a -> ReferenceFrame 
frame = undefined 

localise :: (Vectorise a) => ReferenceFrame -> a -> Local a 
localise = undefined 

class RFunctor f where 
    type SubCats f a :: Constraint 
    type SubCats f a =() 
    rfmap :: (SubCats f a, SubCats f b) => (a -> b) -> f a -> f b 

instance RFunctor Local where 
    type SubCats Local a = Vectorise a 
    rfmap f geom = localise (frame geom) (f $ local geom) 

.

İlgili konular