我使用类型横向幻影类型(状态)来更改记录字段的类型(通过类型族)。如何取回价值?
假设我有以下代码:
{-# LANGUAGE TypeFamilies, DataKinds #-}
data Status = Valid | Invalid deriving(Show)
data A s = A (TF s)
type family TF (s:: Status) where
TF Valid = Int
TF Invalid = Either String Int
status :: A s -> Status
status = ???
如何写入状态?
更新
为了澄清,s
是Status类型的值。因此,我期望status (A 3 :: A Valid)
(例如)是Valid
。
更新2
我找到了一个使用typeclass的解决方案(见我自己的答案),但我更喜欢一种将类型降级为其值的方法。
不能简单地编写函数status :: A s -> Status
,因为(在GHC中)函数在运行时不会接收到其类型参数的任何形式的表示,并且在不了解s
的情况下,在类型A s
的参数中没有有用的信息。无论s
是从数据类型升级而来的类型,还是像*
这样的传统类型,这都适用。
为了获得在运行时变化的信息(Status
结果),您必须提供一些在运行时不同的输入。正如您所发现的,这可以是一个类型类上下文,也可以将信息添加到A
本身:
data A (s :: Status) where
A1 :: Int -> A Valid
A2 :: Either String Int -> A Invalid
然后可以通过对参数进行模式匹配来实现CCD_ 11。
键入类工作,但您需要向下滚动所有案例
class HasStatus where
status :: s -> status
instance HasStatus (A Valid) where
status = const Valid
instance HasStatus (A Invalid) where
status = const Invalid