2016-01-10 18 views
8

reflection paketYansıma riski tutarsızlık mı?

reify :: a -> (forall s . Reifies s a => Proxy s -> r) -> r 

Verilen bir sınıf

class Reifies s a | s -> a where 
    reflect :: proxy s -> a 

ve bir işlev sunan tek bunlar, tek olabilir oldukça kötü örneğin örneğini

instance Reifies s Int where 
    reflect _ = 0 
vererek berbat etmek

Bu, örneğin

için kötü olurdu yasal olarak 1 (normal yansıtma işlemi aracılığıyla) veya 0 ( reify uygulanmadan önce geçilen işlevi uzmanlaştırarak) üretebilir. Gerçekte, bu özel istismarın,numaralı telefona bir Reifies örneğinin dahil edilmesiyle engellenmesi gerektiği görülmektedir. Tanımladığım kötülük örneği örtüşen olarak reddedilecek. Çakışan örnekler etkinleştirilirse, uzmanlaşmanın örtüşen belirsizlik nedeniyle uzmanlığın engellenebileceğine inanıyorum.

Yine de, bunu, GADT'lerin veya bazılarının yardımı ile gölgeli bir örnekle ortaya çıkarmanın bir yolu olup olmadığını merak ediyorum.

cevap

4

Geçici olarak tutarsızlık riski taşımadığını söylüyorum. Bir üzerinde `SPECIALIZE` kullanarak ben GHC kandırdın olabilir acaba ...

{-# LANGUAGE 
    TypeFamilies, FlexibleInstances, MultiParamTypeClasses, 
    ScopedTypeVariables #-} 

import Data.Constraint 
import Data.Proxy 
import Data.Reflection 

instance {-# INCOHERENT #-} Reifies (s :: *) Int where 
    reflect _ = 0 

reflectThis :: forall (s :: *). Dict (Reifies s Int) 
reflectThis = Dict 

-- prints 0 
main = print $ 
    reify (1 :: Int) $ \(p :: Proxy s) -> 
    case reflectThis :: Dict (Reifies s Int) of 
    Dict -> reflect p 
+0

Hmmm: Bazı müdahalesi sonrasında iyi yolu ben tutarsızlık verecek şekilde şaşırtıcı olmayan yeterli olan reflectINCOHERENT kullanılan kaçırma ile gelebilir Fonksiyon nihayetinde 'reify' 'a geçmiştir. Eve gittiğimde bunu deneyeceğim. – dfeuer

+0

@dfeuer bunu denediniz mi? –