Prove that the constraint on the fact that it holds for the product is satisfied for the product component.

I have a class Cwith instances for one type and for tuples.

class C a

instance C Int

instance (C a, C b) => C (a, b)

Using Regular DictGADT to Fix Constraints

{-# LANGUAGE GADTs #-}
{-# LANGUAGE ConstraintKinds #-}

data Dict c where
    Dict :: c => Dict c

can prove C afrom C (a, b)?

fstDict :: Dict (C (a, b)) -> Dict (C a)
fstDict Dict = ???

I suspect that the immediate answer is no, as it’s fstDict Dict = Dictnot enough, and there are several other possibilities. Is there a way to change Cso that product component restrictions can be restored from product restrictions?

I may incorrectly try to accomplish the same thing as the closest question , however I have the luxury of requiring Dictone or both ends of the category.

data DSL a b where
    DSL :: (Dict C a -> DSL' a b) -> DSL a b

data DSL' a b where
    DSL' :: (C a, C b) => ... -> DSL' a b
+4
2

TypeFamily, , , , .

{-# LANGUAGE GADTs #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}

import GHC.Exts (Constraint)
import Data.Proxy

data Dict c where
    Dict :: c => Dict c

Ctx a, . cdict C Ctx, Ctx, . .

class C a where
    type Ctx a :: Constraint
    cdict :: Proxy a -> CDict a

A cdict Dict, C a, Ctx a a

type CDict a = Dict (C a, Ctx a)

Int

instance C Int where
    type Ctx Int = ()
    cdict _ = Dict

C a, C b

instance (C a, C b) => C (a, b) where
    type Ctx (a, b) = (C a, C b)
    cdict _ = Dict

fstCDict .

fstCDict :: forall a b. CDict (a, b) -> CDict a
fstCDict Dict = case cdict (Proxy :: Proxy a) of Dict -> Dict

C, Show

instance (C a) => C (Maybe a) where
    type Ctx (Maybe a) = (C a, Show a)
    cdict _ = Dict

    Could not deduce (Show a) arising from a use of `Dict'
    from the context (C a)
      bound by the instance declaration ...
    Possible fix:
      add (Show a) to the context of the instance declaration
    In the expression: Dict
    In an equation for `cdict': cdict _ = Dict
    In the instance declaration for `C (Maybe a)'
+1

- Dict:

data CDict a where
    IntDict :: C Int => CDict Int
    PairDict :: C (a, b) => CDict a -> CDict b -> CDict (a, b)

fstCDict :: CDict (a, b) -> CDict a
fstCDict (PairDict fst snd) = fst

, CDict .

+1

Source: https://habr.com/ru/post/1570538/


All Articles