我注意到,测试套件Data.Set只有真正定义Arbitrary Set a合理的a ~ Int,但要避免GHC特殊~,它使用
instance Enum a => Arbitrary (Set a)
Run Code Online (Sandbox Code Playgroud)
如何在Arbitrary (Set Int)不需要任何GHC扩展的情况下确保仅使用实例?在GHC-唯一代码,我会请使用FlexibleInstances或GADTs再任
instance Arbitrary (Set Int)
Run Code Online (Sandbox Code Playgroud)
要么
instance a ~ Int => Arbitrary (Set a)
Run Code Online (Sandbox Code Playgroud)
这可以使用我认为我在Oleg Kiselyov的一篇论文中首次遇到的一个想法,这是一个基础Control.Lens.Equality.
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
Run Code Online (Sandbox Code Playgroud)
现在我可以用了
instance IsInt a => Arbitrary (Set a)
Run Code Online (Sandbox Code Playgroud)
并确信我真的在与之打交道Int.为方便起见,我可以IsInt使用我需要的任何类来限制类,这Int是一个实例:
class (Show a, Read a, Integral a, Arbitrary a) => IsInt a where ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
59 次 |
| 最近记录: |