Haskell类型转换类型类
我在Haskell的几个不同的地方遇到了一个名为Haskell类型转换类型类,haskell,type-level-computation,Haskell,Type Level Computation,我在Haskell的几个不同的地方遇到了一个名为TypeCast的类型类 它相当神秘,我似乎无法完全解析它 class TypeCast a b | a -> b, b -> a where typeCast :: a -> b class TypeCast' t a b | t a -> b, t b -> a where typeCast' :: t -> a -> b class TypeCast'' t a b | t a
TypeCast
的类型类
它相当神秘,我似乎无法完全解析它
class TypeCast a b | a -> b, b -> a where typeCast :: a -> b
class TypeCast' t a b | t a -> b, t b -> a where typeCast' :: t -> a -> b
class TypeCast'' t a b | t a -> b, t b -> a where typeCast'' :: t -> a -> b
instance TypeCast' () a b => TypeCast a b where typeCast x = typeCast' () x
instance TypeCast'' t a b => TypeCast' t a b where typeCast' = typeCast''
instance TypeCast'' () a a where typeCast'' _ x = x
对此代码给出了一个有用但敷衍的注释。要了解更多信息,该页面会指向断开的链接
我看到TypeCast
是一个允许您从一种类型转换到另一种类型的类,但我不明白为什么我们需要TypeCast'
和TypeCast'
看起来这段代码所做的只是允许您将类型强制转换为自身。在我看到的一些示例代码中,我尝试将其替换为:
class TypeCast a b | a -> b, b -> a where typeCast :: a -> b
instance TypeCast a a where typeCast a = a
而且样本仍然有效。我一直在看的样本大多来自第一个链接
我想知道是否有人能解释这六行是用来做什么的。TypeCast实际上是用来做什么的? 它不用于检索关于存在类型的类型信息(这会破坏类型系统,因此不可能)。要理解
TypeCast
,我们首先必须了解haskell类型系统的一些特定细节。考虑以下动机示例:
data TTrue
data TFalse
class TypeEq a b c | a b -> c
instance TypeEq x x TTrue
instance TypeEq x y TFalse
这里的目标是在类型级别上有一个布尔标志,它告诉您两个类型是否相等。您可以使用~
进行类型等效-但这只会导致类型等效失败(即Int~Bool
不编译,而TypeEq Int Bool r
将r~TFalse
作为推断类型)。但是,这不会编译-函数依赖项冲突。原因很简单-xx
只是xy
的一个实例(即x~y
=>xy==xx
),因此根据fundeps的规则(有关规则的详细信息,请参阅文档),这两个实例的c
值必须相同(或者这两个值必须是彼此的疯狂,而事实并非如此)
TypeEq
类存在于HList
库中-让我们看看它是如何实现的:
class HBool b => TypeEq x y b | x y -> b
instance TypeEq x x HTrue
instance (HBool b, TypeCast HFalse b) => TypeEq x y b
-- instance TypeEq x y HFalse -- would violate functional dependency
当然,这些实例并不冲突-HTrue
是b
的一个实例。但是等等!难道TypeCast HFalse b
不意味着b
必须是HFalse
?是的,但编译器在试图解决fundep冲突时不检查类实例约束。这是关键的“专长”“ure”,它允许此类存在。
简单地说,这两个实例仍然是重叠的。但是对于-xundecidableincess-XOverlappingInstances
,编译器会优先选择第一个实例,因为第一个实例更“特定”(在本例中,这意味着它最多有2个唯一类型-x
和HTrue
,而另一个实例最多有3个)。您可以在文档中找到不可判定实例
使用的全套规则
为什么排版是这样写的?
如果您在源代码中查找HList,则有多个TypeCast
的实现。其中一个实现是:
instance TypeCast x x
根据包含上述定义的文件中的注释,我们可以假设一个简单的实例将起作用
A generic implementation of type cast. For this implementation to
work, we need to import it at a higher level in the module hierarchy
than all clients of the class. Otherwise, type simplification will
inline TypeCast x y, which implies compile-time unification of x and y.
也就是说,类型简化器(其工作是删除类型同义词和常量类约束的使用)将在TypeCast x
中看到x~y
,因为这是唯一匹配的实例,但仅在某些情况下匹配。由于在不同情况下表现不同的代码“非常糟糕”,HList的作者有第二个实现,即您在原始帖子中的实现。让我们看看:
class TypeCast a b | a -> b, b -> a
class TypeCast' t a b | t a -> b, t b -> a
class TypeCast'' t a b | t a -> b, t b -> a
instance TypeCast' () a b => TypeCast a b
instance TypeCast'' t a b => TypeCast' t a b
instance TypeCast'' () a a
在这种情况下,TypeCast x y
在不查看类约束的情况下(简化程序不会这么做!)是无法简化的;没有实例头可以暗示x~y
但是,我们仍然需要在某个时间点断言x~y
,因此我们使用更多的类来实现这一点!
在TypeCast a b
中,我们能知道a~b
的唯一方法是如果TypeCast()a b
意味着a~b
。只有TypeCast''()a b
意味着a~b
,情况才是这样
不幸的是,我不能告诉你整个故事,我不知道为什么
instance TypeCast' () a b => TypeCast a b
instance TypeCast' () a a
这还不够(它可以工作-我不知道为什么不使用)。我怀疑它与错误消息有关。我相信你可以找到Oleg并问他!TypeCast的实际用途是什么? 它不用于检索存在类型的类型信息(这将破坏类型系统,因此不可能)。为了理解<代码>类型转换> /代码>,我们首先必须了解Haskell类型系统的一些具体细节。
data TTrue
data TFalse
class TypeEq a b c | a b -> c
instance TypeEq x x TTrue
instance TypeEq x y TFalse
这里的目标是在类型级别上有一个布尔标志,它告诉您两种类型是否相等。您可以使用~
进行类型等效,但这只会导致类型等效失败(即Int~Bool
不编译,而typeq Int Bool r
将r~TFalse
作为推断类型)。但是,这不会编译-函数依赖项冲突。原因很简单-x
只是xy
的一个实例(即x~y
=>xy==xx
),因此根据fundeps的规则(有关规则的详细信息,请参阅文档),这两个实例的c
值必须相同(或者这两个值必须是彼此的不一致,而它们不是)
TypeEq
类存在于HList
库中-让我们看看它是如何实现的:
class HBool b => TypeEq x y b | x y -> b
instance TypeEq x x HTrue
instance (HBool b, TypeCast HFalse b) => TypeEq x y b
-- instance TypeEq x y HFalse -- would violate functional dependency
当然这些实例并不冲突-HTrue
是b
的一个实例。但是等等!难道TypeCast HFalse b
不意味着b
必须是HFalse
?是的,我