gpt4 book ai didi

haskell - 类型类 : function with default implementation vs separate function

转载 作者:行者123 更新时间:2023-12-03 23:31:59 25 4
gpt4 key购买 nike

在定义类型类时,您如何决定在类型类的定义中包含/排除函数?例如,这两种情况有什么区别:

class Graph g where
...

insertNode :: g -> Node -> g
insertNode graph node = ...

对比
class Graph g where
...

insertNode :: (Graph g) => g -> Node -> g
insertNode graph node = ...

最佳答案

我认为这里有一些紧张因素。一般认为类型类定义应该是 最小 , 并且只包含 独立 功能。正如 bhelkir 的回答所解释的,如果您的类(class)支持函数 a , bc , 但是 c可以根据 a 来实现和 b ,这是定义 c 的参数课外。

但是这个总体思路遇到了其他一些相互矛盾的问题。

首先,通常有不止一个最小的操作集可以等效地定义同一个类。 Monad的经典定义在 Haskell 中是这样的(清理了一下):

class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b

但众所周知,还有其他定义,例如:
class Applicative m => Monad m where
join :: m (m a) -> m a
return>>=足以实现 join , 但是 fmap , purejoin也足以实现 >>= .

Applicative 类似的事情.这是规范的 Haskell 定义:
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b

但以下任何一项都是等价的:
class Functor f => Applicative f where
unit :: f ()
(<*>) :: f (a -> b) -> f a -> f b

class Functor f => Applicative f where
pure :: a -> f a
fpair :: f a -> f b -> f (a, b)

class Functor f => Applicative f where
unit :: f ()
fpair :: f a -> f b -> f (a, b)

class Functor f => Applicative f where
unit :: f ()
liftA2 :: (a -> b -> c) -> f a -> f b -> f c

给定这些类定义中的任何一个,您可以将任何其他方法中的任何方法编写为类外部的派生函数。为什么第一个被选中?我不能权威地回答,但我认为它把我们带到了第三点: 性能考虑 . fpair其中许多操作结合了 f af b通过创建元组来获取值,但对于 Applicative 的大多数用途class 我们实际上并不想要那些元组,我们只想组合从 f a 中提取的值和 f b ;规范定义允许我们选择使用什么函数来进行这种组合。

另一个性能考虑是,即使类中的某些方法可以根据其他方法定义,这些通用定义对于类的所有实例可能不是最优的。如果我们采取 Foldable例如, foldMapfoldr是可相互定义的,但有些类型比另一种更有效地支持一种。所以我们经常有非最小的类定义来允许实例提供优化的方法实现。

关于haskell - 类型类 : function with default implementation vs separate function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28972612/

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