这是上一个问题的后续:Type-level Map with DataKinds ,从收到的两个答案开始。
我的目标是获取任意类型的 HList
并将其转换为相关/派生类型的列表
type family TypeMap (a :: * -> *) (xs :: [*]) :: [*]
type instance TypeMap t '[] = '[]
type instance TypeMap t (x ': xs) = t x ': TypeMap t xs
data HList :: [*] -> * where
HNil :: HList '[]
HCons :: a -> HList as -> HList (a ': as)
当我实际尝试使用几种类型来执行此操作时,我遇到了问题。 TypeMap 的 type-function "参数必须将 HList
元素类型作为其最后一个参数并返回一个新类型。有时这可以正常工作:
test :: HList rqs -> HList (TypeMap ((,) Int) rqs)
test HNil = HNil
test (HCons x xs) = HCons (3,x) $ test xs
但是如果我想切换 test 定义中元组的顺序怎么办? 我的第一次尝试是定义一个类型同义词:
type RevIntTup b = (b,Int)
test2 :: HList rqs -> HList (TypeMap RevIntTup rqs)
test2 HNil = HNil
test2 (HCons x xs) = HCons (x,3) $ test2 xs
当然,you can't partially apply type synonyms ,这肯定能达到目的。有没有任何(其他)方法可以实现这一目标?
最佳答案
您应该能够编写 FlipTypeMap
...但这不太可组合。这里更好的选择可能是执行类型级别版本的 map ($2) (map (/) [1,2,3])
而不是 map (flip (/) 2) [1,2,3]
通过利用 -XPolyKinds
:
type family TypeMap (a :: j -> k) (xs :: [j]) :: [k]
type instance TypeMap t '[] = '[]
type instance TypeMap t (x ': xs) = t x ': TypeMap t xs
type family ApList (xs :: [j -> k]) (a :: j) :: [k]
type instance ApList '[] t = '[]
type instance ApList (x ': xs) t = x t ': ApList xs t
test2 :: HList rqs -> HList (TypeMap (,) rqs `ApList` Int)
test2 HNil = HNil
test2 (HCons x xs) = HCons (x,3) $ test2 xs
关于haskell - 匿名类型函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19210329/