gpt4 book ai didi

haskell - (ML) 模块与 (Haskell) 类型类

转载 作者:行者123 更新时间:2023-12-03 11:42:23 24 4
gpt4 key购买 nike

根据 Harper (https://existentialtype.wordpress.com/2011/04/16/modules-matter-most/) 的说法,类型类似乎根本没有提供与模块提供的相同级别的抽象,我很难确切地弄清楚原因。该链接中没有示例,因此我很难看到关键差异。还有其他关于如何在模块和类型类之间进行转换的论文( http://www.cse.unsw.edu.au/~chak/papers/modules-classes.pdf ),但这与程序员的实现没有任何关系(它只是说没有什么可以做的对方无法模仿)。

具体来说,在 first link :

The first is that they insist that a type can implement a type class in exactly one way. For example, according to the philosophy of type classes, the integers can be ordered in precisely one way (the usual ordering), but obviously there are many orderings (say, by divisibility) of interest. The second is that they confound two separate issues: specifying how a type implements a type class and specifying when such a specification should be used during type inference.



我也不明白。一个类型可以在 ML 中以多种方式实现一个类型类?在不创建新类型的情况下,您将如何通过示例对整数进行可除性排序?在 Haskell 中,您必须执行类似使用数据的操作并拥有 instance Ord提供替代订购。

第二个,这两者在 Haskell 中不是不同的吗?
指定“在类型推断期间何时应使用此类规范”可以通过以下方式完成:
blah :: BlahType b => ...

其中 BlahType 是在类型推断期间使用的类,而不是实现类。而“类型如何实现类型类”是使用 instance 完成的。 .

有人可以解释链接真正想说的是什么吗?我只是不太明白为什么模块会比类型类限制更少。

最佳答案

要理解这篇文章的意思,请花点时间考虑一下 Monoid Haskell 中的类型类。幺半群是任何类型,T ,它有一个函数 mappend :: T -> T -> T和身份元素mempty :: T以下是成立的。

a `mappend` (b `mappend` c) == (a `mappend` b) `mappend` c
a `mappend` mempty == mempty `mappend` a == a
有许多符合此定义的 Haskell 类型。一个立即浮现在脑海中的例子是整数,我们可以为它定义以下内容。
instance Monoid Integer where
mappend = (+)
mempty = 0
您可以确认所有要求都成立。
a + (b + c) == (a + b) + c
a + 0 == 0 + a == a
事实上,这些条件适用于所有加法的数字,因此我们也可以定义以下内容。
instance Num a => Monoid a where
mappend = (+)
mempty = 0
所以现在,在 GHCi 中,我们可以执行以下操作。
> mappend 3 5
8
> mempty
0
特别细心的读者(或有数学背景的读者)现在可能已经注意到我们也可以定义 Monoid例如乘法上的数字。
instance Num a => Monoid a where
mappend = (*)
mempty = 1

a * (b * c) == (a * b) * c
a * 1 == 1 * a == a
但是现在编译器遇到了问题。 mappend 的哪个定义它应该用于数字吗?是否 mappend 3 5等于 815 ?它没有办法决定。这就是 Haskell 不允许单个类型类的多个实例的原因。但是,问题仍然存在。其中 Monoid Num 的实例我们应该使用吗?两者都是完全有效的,并且在某些情况下是有意义的。解决方案是两者都不使用。如果你看 Monoid在 Hackage 中,你会看到没有 Monoid Num 的实例, 或 Integer , Int , Float , 或 Double对于这个问题。相反,有 Monoid Sum 的实例和 Product . SumProduct定义如下。
newtype Sum a = Sum { getSum :: a }
newtype Product a = Product { getProduct :: a }

instance Num a => Monoid (Sum a) where
mappend (Sum a) (Sum b) = Sum $ a + b
mempty = Sum 0

instance Num a => Monoid (Product a) where
mappend (Product a) (Product b) = Product $ a * b
mempty = Product 1
现在,如果你想使用一个数字作为 Monoid您必须将其包装在 Sum 中或 Product类型。您使用哪种类型决定了 Monoid使用实例。这就是这篇文章试图描述的本质。 Haskell 的类型类系统中没有内置系统允许您在多个实例之间进行选择。相反,您必须通过在骨架类型中包装和展开它们来跳过箍。现在,您是否认为这是一个问题,很大程度上决定了您更喜欢 Haskell 还是 ML。
ML 通过允许在不同模块中定义相同类和类型的多个“实例”来解决这个问题。然后,您导入的模块决定了您使用的“实例”。 (严格来说,ML 没有类和实例,但它确实有签名和结构,它们的作用几乎相同。更深入的比较,请阅读 this paper)。

关于haskell - (ML) 模块与 (Haskell) 类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36927169/

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