【发布时间】:2021-05-16 13:40:35
【问题描述】:
是否有任何机制可以在 Haskell 中强制约束(除了我希望有效的 unsafeCoerce)?
{-# 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)
【问题讨论】:
-
你到底在问什么?
instance c a => c ((K a) b)给我一个非常糟糕的主意。但这不是标题似乎要问的。那么,...? -
另外,
ok的签名与那些阴影类型变量等等看起来很糟糕。你不能再简化一下场景吗? (而且我个人发现∀比forall更清楚地表明了这样的签名。) -
a与K a i“相同”。每个实例a拥有,K a I也应该拥有。我可以将deriving via用于我想的任何约束c,这要归功于强制。所以我想将a上的所有实例提升到K a i。 -
我同意,这是一个丑陋的签名.. 不知道如何使它更好。我可以用
proxy a替换a。 -
标签: haskell deriving derivingvia