【发布时间】:2019-12-25 18:56:54
【问题描述】:
在 Haskell 中,我发现很难完全理解 kind 系统的目的,以及它真正为语言添加了什么。
我知道有种类会增加安全性。
例如,考虑 fmap :: (a -> b) -> f a -> f b 与它的单一版本 fmap2 :: (a -> b) -> p -> q。
我的理解是,多亏了 kind 系统,我可以更详细地预先指定数据的形状应该是什么。更好,因为类型检查器可以检查更多,更严格的要求将减少用户弄乱类型的可能性。这将减少编程错误的可能性。我相信这是种类的主要动机,但我可能错了。
现在我认为 fmap2 可以具有与 fmap 相同的实现,因为它的类型不受约束。是真的吗?
是否可以将 base/ghc 库中的所有多类型类型替换为单类型类型,并且仍然可以正确编译?
为了澄清一点,我的意思是对于像这样的类:
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
我可能会用类似的东西替换它
class Functor a b p q where
fmap :: (a -> b) -> p -> q
(<$) :: a -> q -> p
这种方式适用于Functor 这样的实例
instance Functor [] where fmap = map
我可能会替换为
instance Functor a b p q where fmap = map
备注:这不会按原样工作,因为我还需要修改 map 并沿着依赖链向下走。稍后会考虑更多..
我想弄清楚种类是否不仅仅增加了安全性?我可以用多类类型做一些我不能用单类做的事情吗?
备注:在这里我忘了提到我通常使用一些语言扩展,通常是为了在编写类时提供更大的灵活性。 当做香草haskell种类时,使用起来真的很有意义。 但是当我开始使用类型族和其他一些扩展时,我根本不需要种类就变得不那么清楚了。
我记得有一些可单遍历的库,它使用单一种类的类型重新实现了许多标准库函数,并使用类型族来概括签名。这就是为什么我的直觉是,如果一个使用类型族,多类型变量可能不会真正增加那么多的表达能力。然而,这样做的一个缺点是你失去了类型安全性。我的问题是你真的只是失去了那个,还是你真的失去了其他东西。
【问题讨论】:
-
@WillemVanOnsem 是的,所以我是否正确地说 fmap2 比 fmap 更通用,并且它的实现可能相同?
-
我不是类型论专家,我一直在看这篇文章en.wikipedia.org/wiki/Kind_(type_theory),但我很难理解为什么整个类型系统确实存在的深层原因
-
既然有基于类型的函数级编程,就有基于种类的类型级编程,甚至将来可能存在基于排序的种类级编程。 Types and Kinds and Sorts, Oh My! 是一本好书。
-
@J.M.你不正确。比较通用,但是不能实现。
-
fmap的完整类型实际上比您在问题中所说的要长:fmap :: Functor f => (a -> b) -> f a -> f b。对于您提议的替代类型,您将如何陈述类似于Functor f的约束?
标签: haskell type-kinds