【发布时间】:2016-02-07 10:54:14
【问题描述】:
我正在尝试编写两个函数来从 HList 中提取值,但我似乎无法让 GHC 满意。
第一个函数将具有签名extract :: HList a -> [b],它从列表中提取b 类型的所有元素。我只是通过要求a 中的类型拥有Typeable 实例才成功编写它。
class OfType a b where
oftype :: a -> [Maybe b]
instance OfType (HList '[]) b where
oftype = const []
instance (Typeable t, Typeable b, OfType (HList ts) b) => OfType (HList (t ': ts)) b where
oftype (x :- xs) = (cast x :: Maybe b) : oftype xs
extract :: OfType a b => a -> [b]
extract = catMaybes . oftype
这是次优的,因为实际上并不需要 Typeable 约束来编写任何提取实例。
我尝试在约束中使用类型等式和不等式,但这只会给我重叠的实例。
我尝试编写的第二个函数将具有签名extract' :: Contains h n => HList h -> n,它提取列表中n 类型的第一个元素,并且上下文表明该列表实际上包含该类型的一个元素。
是否可以在没有Typeable 约束的情况下编写extract?
是否可以在没有Typeable 约束的情况下编写extract'?
怎么写Contains?
【问题讨论】:
-
你想要的是
Data.HList.Occurs中的hOccurs和hOccursMany。不过他们不支持Num a => HList '[Char, a, Char]之类的东西。 -
我似乎无法让
hOccurs工作,我正在使用hOccursFst (HCons 'a' HNil) :: Char。我错过了什么吗? -
对不起,我没有仔细检查。
hOccursFst但不是hOccurs满足您的要求。再次抱歉。 -
我的意思是
hOccursFst不适合我,抱歉 -
您能否将您的确切用例附加到您的问题中?
hOccursFst (HCons 'a' HNil) :: Char在 ghci 中为我工作。没有语言扩展,我唯一导入的是Data.HList。