Partially applicable type with view (* & # 8594; Constraint)

Consider the following code:

class Foo f
class Bar b

newtype D d = D

call :: Proxy c -> (forall a . c a => a -> Bool) -> x -> Bool
call g x = g x

-- this function is Testable, and can be used by QuickCheck
f :: (Foo (D d), Bar d) => D d -> Bool
f = error ""

//assume the type FConstraint has kind (* -> Constraint)

main = print $ call (Proxy::Proxy FConstraint) (unsafeCoerce f) (D::D 17)

The purpose of such a strange feature - easily check polymorphic functions (for example f) using QuickCheck: callwill be renamed in the list of types of monomorphic types, and this list can be used for several different properties (all take one argument) without explicitly writing out the type signatures each time. Since this only appears in the test code, I am ready to use it unsafeCoerce(although I'm not sure that it will do what I want at this moment. I need to first solve the question below).

, , / call, , : FConstraint (* -> Constraint), call.

:

type FConstraint x = (Foo x, Bar ??)
type FConstraint (D d) = (Foo (D d), Bar d)

, , , FConstraint, .

:

type family FConstraint x
type instance FConstraint (D d) = (Foo (D d), Bar d)

( ).

, (* -> Constraint),

  • *

UPDATE

, :

{-# LANGUAGE RankNTypes, ScopedTypeVariables, ConstraintKinds, TypeOperators,
             MultiParamTypeClasses, DataKinds, PolyKinds, FlexibleInstances,
             UndecidableInstances, FlexibleContexts, TypeFamilies,
             FunctionalDependencies #-}

import Control.Monad
import Data.Proxy
import GHC.Prim
import GHC.TypeLits
import Test.QuickCheck
import Test.Framework
import Test.Framework.Providers.QuickCheck2
import Unsafe.Coerce

newtype Zq q = Zq Integer deriving (Show, Eq)

instance (KnownNat q) => Arbitrary (Zq q) where
  arbitrary = liftM (\i -> Zq $ (i `mod` (natVal (Proxy::Proxy q)))) arbitrary

instance (KnownNat q) => Num (Zq q) where
  (Zq a) + (Zq b) = Zq $ (a + b) `mod` (natVal (Proxy::Proxy q))
  (Zq a) * (Zq b) = Zq $ (a * b) `mod` (natVal (Proxy::Proxy q))
  negate (Zq 0) = (Zq 0)
  negate (Zq a) = Zq $ (natVal (Proxy::Proxy q)) - a
  fromInteger x = Zq $ x `mod` (natVal (Proxy::Proxy q))

f :: (KnownNat q) => Zq q -> Zq q
f x = x + 1

finv :: (KnownNat q) => Zq q -> Zq q
finv x = x - 1

prop_f :: forall q . (KnownNat q) => Zq q -> Bool
prop_f x = (finv . f) x == x

call :: (c x) => Proxy (c :: * -> Constraint) -> 
        (forall a . c a => a -> Bool) -> 
        x -> 
        Bool
call _ f = f

class UnZq zq q | zq -> q
instance UnZq (Zq q) q

class FConstraint x
instance (KnownNat q, UnZq zq q) => FConstraint zq

main = defaultMain $ [testProperty "zq_f_id" $ property $
         (call (Proxy::Proxy FConstraint) $ unsafeCoerce prop_f :: Zq 3 -> Bool)]

:

Could not deduce (KnownNat q0) arising from a use of ‘prop_f’
from the context (FConstraint a)

, ...

:

type MyTypes = '[ Zq 3, Zq 5, Zq 7, Zq 11 ] 

class TypesToProps xs c where
  tmap :: Proxy xs -> Proxy c -> (forall a . c a => a -> Bool) -> [Property]

instance TypesToProps '[] c where
  tmap _ _ _ = []

instance (c x, TypesToProps xs c, Arbitrary x, Show x)
    => TypesToProps (x ': xs) c where
  tmap _ c f = (property (call c f :: x -> Bool)) : (tmap (Proxy::Proxy xs) c f)

-- results in same error as the `main` above
main = defaultMain $ map (testProperty "zq_f_id") $ 
         tmap (Proxy::Proxy MyTypes) 
              (Proxy::Proxy FConstraint) 
              (unsafeCoerce prop_f)
+4
1

-, call : c x Proxy c -> (forall a . c a => a -> Int) -> x -> Int, x f.

, unsafeCoerce . unsafeCoerce, :

withCall 
  :: (forall d . (Foo (D d), Bar d) => D d -> Bool) 
  -> (forall a . FConstraint a => a -> Int)
withCall = unsafeCoerce

D d Bool Int. ( , ImpictictiveTypes). , , , unsafeCoerce, , , , .

FConstraint :

class UnD x (y :: Nat) | x -> y 
instance UnD (D x) x 

class FConstraint x
instance (Foo x, Bar t, UnD x t) => FConstraint x

:

{-# LANGUAGE 
    UndecidableInstances
  , ImpredicativeTypes
  , MultiParamTypeClasses
  , FunctionalDependencies 
  #-}

import Unsafe.Coerce 
import GHC.Exts (Constraint)
import Data.Proxy 
import GHC.TypeLits 

class Foo f
class Bar (b :: Nat)

data D (d :: Nat) = D

call :: Proxy (c :: * -> Constraint) -> (forall a . c a => a -> Int) -> x -> Int
call = undefined

f :: (Foo (D d), Bar d) => D d -> Bool
f = error ""

withCall :: (forall d . (Foo (D d), Bar d) => D d -> Bool) -> (forall a . FConstraint a => a -> Int)
withCall = unsafeCoerce

class UnD x (y :: Nat) | x -> y 
instance UnD (D x) x 

class FConstraint x
instance (Foo x, Bar t, UnD x t) => FConstraint x

main = print $ call (Proxy :: Proxy FConstraint) (withCall f) (D :: D 17)

, , TypesToProps:

class TypesToProps xs (c :: k -> Constraint) (t :: k -> *) where
  tmap :: Proxy xs -> Proxy c -> Proxy t -> (forall a . c a => t a -> Bool) -> [Property]

instance TypesToProps '[] c t where
  tmap _ _ _ _ = []

instance (c x, TypesToProps xs c t, Arbitrary (t x), Show (t x)) => TypesToProps (x ': xs) c t where
  tmap _ c t f = property (f :: t x -> Bool) : tmap (Proxy :: Proxy xs) c t f

main = defaultMain $ map (testProperty "zq_f_id") $ 
  tmap (Proxy :: Proxy '[3, 5, 7, 11]) 
       (Proxy :: Proxy KnownNat) 
       (Proxy :: Proxy Zq)
       prop_f

, unsafeCoerce.

unsafeCoerce prop_f, , KnownNat q , - . , , , .

( ):

data Dict p where 
  Dict :: p => Dict p 

, :

anyDict :: Dict p 
anyDict = unsafeCoerce (Dict :: Dict (Eq ()))

prop_f' :: forall q . Zq q -> Bool
prop_f' q = case anyDict :: Dict (KnownNat q) of Dict -> prop_f q 

, , q in Zq q phantom -, Zq, q , .

class TypesToProps xs where
  tmap :: Proxy xs -> (forall a . a -> Bool) -> [Property]

instance TypesToProps '[] where
  tmap _ _ = []

instance (TypesToProps xs, Arbitrary x, Show x) => TypesToProps (x ': xs) where
  tmap _ f = property (f :: x -> Bool) : tmap (Proxy :: Proxy xs) f where

, forall a . a -> Bool , unsafe. , , tmap; , tmap. :

main = defaultMain $ map (testProperty "zq_f_id") $ 
  tmap (Proxy :: Proxy '[Zq 3, Zq 5, Zq 7, Zq 11]) 
       (unsafeCoerce prop_f' :: forall a . a -> Bool) 
+3

All Articles