我使用类型横向幻像类型(状态)来更改记录字段的类型(通过类型族)。我怎样才能获得价值?
我们说我有以下代码:
{-# 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
。
我找到了一个带类型类的解决方案(请参阅我自己的回答),但我更倾向于将类型降级为其值。
答案 0 :(得分:2)
你不能简单地编写你的函数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
然后你可以通过对参数进行模式匹配来实现status
。
答案 1 :(得分:0)
键入类工作,但您需要向下滚动所有案例
class HasStatus where
status :: s -> status
instance HasStatus (A Valid) where
status = const Valid
instance HasStatus (A Invalid) where
status = const Invalid