2016-08-05 26 views
7

Ben Nasıl emin sadece Arbitrary (Set Int) örneği herhangi GHC uzantıları gerek kalmadan kullanılır yapabilirsiniz Data.Set için test paketi sadece gerçekten a ~ Int için makul Arbitrary Set a tanımlar fakat GHC özel ~ onasıl Haskell 98 belirli bir tip uygulama için bir örneğini tanımlayabiliriz?

instance Enum a => Arbitrary (Set a) 

kullanır önlemek için fark ? GHC okunur kodunda, Kullanayım ya FlexibleInstances veya GADTs ve sonra ya

instance Arbitrary (Set Int) 

veya

instance a ~ Int => Arbitrary (Set a) 

cevap

6

Bu benim ilk Oleg KISELYOV bir yazıda karşılaşılan düşünüyorum bir fikir kullanmak mümkün; ve hangisi Control.Lens.Equality'un altındadır.

import Data.Functor.Identity 

class IsInt a where 
    fromIntF :: f Int -> f a 

instance IsInt Int where 
    fromIntF fx = fx 

toIntF :: IsInt a => g a -> g Int 
toIntF = unf . fromIntF . F $ id 

newtype F g a b = F {unf :: g b -> a} 

fromInt :: IsInt a => Int -> a 
fromInt = runIdentity . fromIntF . Identity 

toInt :: IsInt a => a -> Int 
toInt = runIdentity . toIntF . Identity 

Şimdi

instance IsInt a => Arbitrary (Set a) 

kullanmak ve gerçekten Int uğraşıyorum emin olabiliriz. Bu size sistemin dışında istediğiniz garantisi verir ama değil içindeki: Bu kayda değer olabilir

class (Show a, Read a, Integral a, Arbitrary a) => IsInt a where ... 
+3

: kolaylık olması açısından, Int bir örnek olduğu ihtiyacım herhangi sınıfları ile IsInt sınıf kısıtlayabilir. Yani GHC IsInt 'bir ~ Int' a'' dan çıkarmak olmaz vardır. Bu bazen can sıkıcı ek tür ek açıklamaları gerektirebilir. Bunun sadece H98 (ya da H2010) içinde olmasına yardımcı olabileceğini sanmıyorum. –

+0

@DanielWagner, evet, ghc yaklaşımına kesinlikle gerisinde. Eşitlik kısıtlamaları standartlaştırılmışsa, kesinlikle onları tercih ederim. Ama 'containers' genellikle mümkün olduğunca "taşınabilir" olarak olmaya çalışır, bu yüzden ben bir uzantısı olmadan gerekenleri yapabiliyorsa, yaparım. ~: Int' IsInt a => Int 'Çeşidi şey almak için: ~ – dfeuer

+1

@DanielWagner, ben' refl :: Int bu uygulama ki size 'fromIntF' uygulayabilir, GHC en uyumlu olduğunu belirterek, aynı zamanda değer olduğunu düşünüyorum : a. Gerçekten de bu, dile nasıl uyduğuna bakılmaksızın, benzer bir eşitlik türü için çalışacaktır. – dfeuer