【发布时间】:2015-06-24 05:33:34
【问题描述】:
我能否让编译器相信封闭类型族中的类型同义词始终满足约束?该族由一组有限的提升值索引。
类似的东西
data NoShow = NoShow
data LiftedType = V1 | V2 | V3
type family (Show (Synonym (a :: LiftedType)) => Synonym (a :: LiftedType)) where
Synonym V1 = Int
Synonym V2 = NoShow -- no Show instance => compilation error
Synonym V3 = ()
我可以对开放类型族实施约束:
class (Show (Synonym a)) => SynonymClass (a :: LiftedType) where
type Synonym a
type Synonym a = ()
instance SynonymClass Int where
type Synonym V1 = Int
-- the compiler complains here
instance SynonymClass V2 where
type Synonym V2 = NoShow
instance SynonymClass V3
但是编译器必须能够推断出V1、V2 和V3 中的每一个都存在SynonymClass a 的实例?但无论如何,我宁愿不使用开放类型族。
我要求这样做的动机是我想说服编译器我的代码中所有封闭类型族的实例都有 Show/Read 实例。一个简化的例子是:
parseLTandSynonym :: LiftedType -> String -> String
parseLTandSynonym lt x =
case (toSing lt) of
SomeSing (slt :: SLiftedType lt') -> parseSynonym slt x
parseSynonym :: forall lt. SLiftedType lt -> String -> String
parseSynonym slt flv =
case (readEither flv :: Either String (Synonym lt)) of
Left err -> "Can't parse synonym: " ++ err
Right x -> "Synonym value: " ++ show x
[有人在 cmets 中提到这是不可能的 - 这是因为这在技术上是不可能的(如果是,为什么)或者只是 GHC 实施的限制?]
【问题讨论】:
-
我也想要这个,但不幸的是,据我所知这是不可能的。尽管我认为使用单例,但您只需要 1 个类。
-
为什么不只是
parseF :: forall lt. (Read (Synonym lt), Show (Synonym lt)) => SLiftedType lt -> String -> String?据我了解,它足以满足您的目的。 -
@AndrásKovács 我为我的激励示例添加了一些进一步的上下文。
SLiftedType lt的值事先不知道 - 我试图将(String, String)解析为(LiftedType, String),然后解析为(SLiftedType lt, Synonym lt),但将依赖类型的部分隐藏在SomeSingcase 语句中。 -
@bennofs - 只需要一节课是什么意思?
-
@dbeacham 我不认为这会排除我的提议。只需对
SomeSing slt中的slt进行模式匹配,您就可以在那里处理不可显示/不可读取的情况。
标签: haskell type-families