gpt4 book ai didi

haskell - 带有 DataKinds 的类型级映射

转载 作者:行者123 更新时间:2023-12-02 04:08:14 24 4
gpt4 key购买 nike

我有一个常见的模式,其中有一个 [*] 类型的类型级列表,并且我想应用 * -> * 类型的类型构造函数> 到列表中的每个元素。例如,我想将类型 '[Int, Double, Integer] 更改为 '[Maybe Int, Maybe Double, Maybe Integer]

这是我尝试实现类型级映射

{-# LANGUAGE TypeFamilies, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, TypeOperators, DataKinds, ScopedTypeVariables, GADTs #-}

-- turns a type list '[b1, b2, b3]
-- into the type list '[a b1, a b2, a b3]
class TypeMap (a :: * -> *) (bs :: [*]) where
type Map a bs :: [*]

instance TypeMap a '[b] where
type Map a '[b] = '[a b]

instance TypeMap a (b1 ': b2 ': bs) where
type Map a (b1 ': b2 ': bs) = ((a b1) ': (Map a (b2 ': bs)))


data HList :: [*] -> * where
HNil :: HList '[]
HCons :: a -> HList as -> HList (a ': as)

class Foo as where
toLists :: HList as -> HList (Map [] as)

instance Foo '[a] where
toLists (HCons a HNil) = HCons [a] HNil

instance (Foo (a2 ': as)) => Foo (a1 ': a2 ': as) where
toLists (HCons a as) =
let as' = case (toLists as) of
(HCons a2 as'') -> HCons [head a2] as'' -- ERROR
in HCons [a] as'

这会导致错误

Could not deduce (a3 ~ [t0])
from the context (Foo ((':) * a2 as))
bound by the instance declaration at Test.hs:35:10-50
or from ((':) * a1 ((':) * a2 as) ~ (':) * a as1)
bound by a pattern with constructor
HCons :: forall a (as :: [*]).
a -> HList as -> HList ((':) * a as),
in an equation for `toLists'
at Test.hs:36:14-23
or from (Map [] as1 ~ (':) * a3 as2)
bound by a pattern with constructor
HCons :: forall a (as :: [*]).
a -> HList as -> HList ((':) * a as),
in a case alternative
at Test.hs:38:22-34
`a3' is a rigid type variable bound by
a pattern with constructor
HCons :: forall a (as :: [*]).
a -> HList as -> HList ((':) * a as),
in a case alternative
at Test.hs:38:22
Expected type: HList (Map [] ((':) * a2 as))
Actual type: HList ((':) * [t0] as2)
In the return type of a call of `HCons'
In the expression: HCons [head a2] as''
In a case alternative: (HCons a2 as'') -> HCons [head a2] as''

我尝试添加大量类型注释,但错误或多或少都是相同的:GHC 甚至无法推断 HList 的第一个元素是(正常)列表。我在这里做傻事了吗?有什么违法的吗?或者有什么办法吗?

最佳答案

当您编写 TypeMap a (b1 ': b2 ': bs) 时,这与您定义 Map 所做的递归不一致...这只会在您尝试时导致错误到长度不是 1 或 2 个元素的 TypeMap 列表。另外,在您的情况下,只有一个类型系列会更干净。

type family TypeMap (a :: * -> *) (xs :: [*]) :: [*]
type instance TypeMap t '[] = '[]
type instance TypeMap t (x ': xs) = t x ': TypeMap t xs

请注意,这几乎是以下内容的直接翻译:

map f [] = []
map f (x:xs) = f x : map f xs

关于haskell - 带有 DataKinds 的类型级映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19191348/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com