Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 什么时候在Typeclass中实现可选函数是个好主意_Haskell_Typeclass - Fatal编程技术网

Haskell 什么时候在Typeclass中实现可选函数是个好主意

Haskell 什么时候在Typeclass中实现可选函数是个好主意,haskell,typeclass,Haskell,Typeclass,我一直在为我制作的一种数据类型实现Foldable,我想知道是否应该在typeclass中实现foldr和其他可选函数 我查阅了文档,但这只是解释了函数,而不是我是否应该在自己的版本上实现它,或者默认版本是否合适。然后我研究了实现,这使得事情变得更加复杂,因为有些函数使用#.而不是来修复某种效率低下的问题,我不确定我的实现是否会消除这些问题,也不确定我是如何发现的 我还尝试用谷歌搜索它,并在堆栈溢出上搜索它,但不幸的是找不到任何相关的内容 那么,我如何决定是否应该实现更复杂类型类的可选功能,如F

我一直在为我制作的一种数据类型实现
Foldable
,我想知道是否应该在typeclass中实现
foldr
和其他可选函数

我查阅了文档,但这只是解释了函数,而不是我是否应该在自己的版本上实现它,或者默认版本是否合适。然后我研究了实现,这使得事情变得更加复杂,因为有些函数使用
#.
而不是
来修复某种效率低下的问题,我不确定我的实现是否会消除这些问题,也不确定我是如何发现的

我还尝试用谷歌搜索它,并在堆栈溢出上搜索它,但不幸的是找不到任何相关的内容

那么,我如何决定是否应该实现更复杂类型类的可选功能,如
Foldable

我喜欢的示例(不理解为什么它不是实际定义的一部分)是
mconcat
for
Product
。提醒

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