gpt4 book ai didi

haskell - 在类实例中需要更高种类的类型

转载 作者:行者123 更新时间:2023-12-04 00:56:48 24 4
gpt4 key购买 nike

我有一个看起来像这样的类型。

data State = Unsanitized | Sanitized

type family BarTy (s :: State) :: Type where
BarTy 'Unsanitized = String
BarTy 'Sanitized = Int

data Foo (a :: State) = Foo (Bar a)
data Bar (a :: State) = Bar (BarTy a)

我使用类型参数来更改某些字段的类型。例如,当通过验证管道演变数据结构时,这非常有用。

现在我想编写一个类,可以从该数据结构中提取一些内容,但它是哪个状态并不重要。完整示例:

data State = Unsanitized | Sanitized

type family BarTy (s :: State) :: Type where
BarTy 'Unsanitized = String
BarTy 'Sanitized = Int

data Foo (a :: State) = Foo (Bar a)
data Bar (a :: State) = Bar (BarTy a)

class Extractor a where
extract :: a -> (BarTy b)

instance Extractor (Foo a) where
extract (Foo x) = extract x

instance Extractor (Bar a) where
extract (Bar x) = x

这显然不起作用,因为 b 类型变量在实例中始终未知,因此会发生类型错误。我可以创建另一个类型系列,从给定类型中提取 State 类型,但这对于较大的类型来说确实很笨重。

data State = Unsanitized | Sanitized

type family BarTy (s :: State) :: Type where
BarTy 'Unsanitized = String
BarTy 'Sanitized = Int

type family ExtractState (t :: Type) :: State where
ExtractState (Foo s) = s
ExtractState (Bar s) = s
ExtractState _ = TypeError ('Text "ExtractState: Passed type is not valid.")

data Foo (a :: State) = Foo (Bar a)
data Bar (a :: State) = Bar (BarTy a)

class Extractor a where
extract :: a -> (BarTy (ExtractState a))

instance Extractor (Foo a) where
extract (Foo x) = extract x

instance Extractor (Bar a) where
extract (Bar x) = x

bar1 :: Bar 'Unsanitized
bar1 = Bar "Test"
foo1 = Foo bar1

bar2 :: Bar 'Sanitized
bar2 = Bar 1337
foo2 = Foo bar2

a = extract bar1
b = extract foo1
c = extract bar2
d = extract foo2

我理想中想做的是在类声明中进行模式匹配,但我不知道如何做到这一点,或者是否可能:

data State = Unsanitized | Sanitized

type family BarTy (s :: State) :: Type where
BarTy 'Unsanitized = String
BarTy 'Sanitized = Int

data Foo (a :: State) = Foo (Bar a)
data Bar (a :: State) = Bar (BarTy a)

class Extractor (t a) where
extract :: (t a) -> (BarTy a)

instance Extractor (Foo a) where
extract (Foo x) = extract x

instance Extractor (Bar a) where
extract (Bar x) = x

Haskell 可以做这样的事情吗?或者还有其他方法可以实现我想要的吗?

感谢任何帮助。

最佳答案

请记住,定义类型类时可以部分应用类型:

class Extractor t where
extract :: t a -> BarTy a

(同样的技术也用在 FunctorApplicativeMonad 的定义中,并且一般来说,任何用于与更高级的类型。)

关于haskell - 在类实例中需要更高种类的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61791917/

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