Is there any mechanism to coerce constraints in Haskell (beside unsafeCoerce
which I hope works)?
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TypeApplications #-}
module CatAdjonctionsSOQuestion where
import Data.Proxy
import Data.Tagged
import Unsafe.Coerce
newtype K a ph = K {unK :: a} -- I would want c a => c ((K a) i) for any c :: Constraints
-- I could do any possible instance by hand
deriving via a instance Semigroup a => Semigroup ((K a) i)
-- I want them all
-- deriving via a instance c ((K a) i) -- Instance head is not headed by a class: c (K a i)
data Exists c where
Exists :: c a => a -> Exists c
data ExistsKai c i where
ExistsKai :: c ((K a) i) => Proxy a -> ExistsKai c i
ok :: forall x c i. (forall x. (forall a. c a => a -> x) -> x) -> (forall a. c ((K a) i) => Tagged a x) -> x
ok s k =
let e = (s Exists :: Exists c)
in let f = unsafeCoerce e :: ExistsKai c i
in case f of (ExistsKai (Proxy :: Proxy a)) -> unTagged (k @a)
With a slight modification to make it kind check, you ask for
newtype K a ph = K {unK :: a}
-- I would want c a => c ((K a) i)
-- for any c :: Type -> Constraint
You absolutely can't get that, now or ever, because it's invalid. Consider
(~) Bool :: Type -> Constraint
Now (~) Bool Bool
holds, but you can never achieve (~) Bool (K Bool i)
.
What about without equality constraints? Well, I can do that too, using Leibniz equality:
class Bar a where
isBool :: f a -> f Bool
instance Bar Bool where
isBool = id
But there is no way to write instance Bar (K Bool i)
whose isBool
doesn't bottom out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With