Haskell 什么时候在Typeclass中实现可选函数是个好主意
我一直在为我制作的一种数据类型实现Haskell 什么时候在Typeclass中实现可选函数是个好主意,haskell,typeclass,Haskell,Typeclass,我一直在为我制作的一种数据类型实现Foldable,我想知道是否应该在typeclass中实现foldr和其他可选函数 我查阅了文档,但这只是解释了函数,而不是我是否应该在自己的版本上实现它,或者默认版本是否合适。然后我研究了实现,这使得事情变得更加复杂,因为有些函数使用#.而不是来修复某种效率低下的问题,我不确定我的实现是否会消除这些问题,也不确定我是如何发现的 我还尝试用谷歌搜索它,并在堆栈溢出上搜索它,但不幸的是找不到任何相关的内容 那么,我如何决定是否应该实现更复杂类型类的可选功能,如F
Foldable
,我想知道是否应该在typeclass中实现foldr
和其他可选函数
我查阅了文档,但这只是解释了函数,而不是我是否应该在自己的版本上实现它,或者默认版本是否合适。然后我研究了实现,这使得事情变得更加复杂,因为有些函数使用#.
而不是
来修复某种效率低下的问题,我不确定我的实现是否会消除这些问题,也不确定我是如何发现的
我还尝试用谷歌搜索它,并在堆栈溢出上搜索它,但不幸的是找不到任何相关的内容
那么,我如何决定是否应该实现更复杂类型类的可选功能,如Foldable
?我喜欢的示例(不理解为什么它不是实际定义的一部分)是mconcat
forProduct
。提醒
class Monoid a where
mempty :: a
mappend :: a -> a -> a
mconcat = foldr mappend mempty
产品
实例如下所示
instance Num a => Monoid (Product a) where
mempty = Product 1
(Product x) `mappend` (Product y) = Product (x * y)
现在,使用默认的mconcat
,mconcat(映射乘积[1..10])
必须将所有数字相乘,才能得到最终的0。(事实上,对于无限列表,函数永远不会终止。)
如果mconcat
已被替换为
mconcat = foldr (\acc v -> if v == Product 0 then Product0 else mappend acc v) mempty
然后,
mconcat
可以在第一次看到列表中的Product 0
时返回Product 0
。如果它们是可操作的,则它们具有默认实现。如果您愿意,您可以实现它们。这实际上非常简单:如果您认为在foldr
方面,您可以用比默认实现效率更高的方式编写其他函数,请随意执行。@Alec说得很简单,但是很难判断我的函数是否比默认实现更好,因为某个函数在不同类型的参数下是如何工作的。例如,严格值与惰性值、函数与非函数、无限值与有限值。因此,要想弄清楚这一点似乎需要很多时间,这似乎需要很多工作来决定是否值得实施我自己的版本。如果你对这一分析持负面看法,这可能意味着实现比默认的foldr
更多的函数将是一个过早的优化。这是一个很好的解释,解释了为什么人们可能希望在TypeClass中添加更多具有默认实现的函数,但OP询问是否在现有的typeclass中使用默认实现实现函数;这是一个例子,说明了您应该在哪里(我不知道为什么产品实例不)提供不同的mconcat`定义。啊!这更有道理——这是一个非常好的观点这可以通过mappend(产品0)\=Product 0
完成,无需涉及mconcat