【问题标题】:Should I use typeclasses or not?我应该使用类型类吗?
【发布时间】:2013-06-14 02:05:05
【问题描述】:

我很难理解在我的代码中何时使用和何时不使用 typeclass。当然,我的意思是创建我自己的,而不是使用已经定义的类型类。举个例子(非常愚蠢的例子),我应该这样做:

data Cars = Brakes | Wheels | Engine
data Computers = Processor | RAM | HardDrive  

class Repairable a where
    is_reparaible :: a -> Bool

instance Repairable Cars where
    is_repairable (Brakes) = True
    is_repairable (Wheels) = False
    is_repairable (Engine) = False

instance Repairable Computers where
    is_repairable (Processor) = False
    is_repairable (RAM)       = False
    is_repairable (HardDrive) = True

checkState :: (Reparaible a) => a -> ... 
checkState a = ...

(显然,这是一个愚蠢的、不完整的例子)。

但是这有很多用处,不是吗?为什么我不应该做一些简单的事情,只定义函数而不定义新的数据类型和类型类(及其实例)。

这个例子太简单了,但实际上我在 github 上浏览 Haskell 代码时经常看到类似的东西(新数据类型+类型类+实例),而不仅仅是定义函数。

那么,什么时候应该创建新的数据类型、类型类等,什么时候应该使用函数?

谢谢。

【问题讨论】:

    标签: haskell


    【解决方案1】:

    为什么我不应该做一些简单而只定义函数的事情 无需定义新的数据类型和类型类(及其 实例)。

    为什么?你可以定义:

    checkState :: (a -> Bool) -> (a -> b) -> (a -> b) -> a -> b
    checkState is_repairable repairs destroy a
        = if (is_repairable a) then repairs a else destroy a
    

    人们一直在滥用类型类。这并不意味着它是惯用的。

    为了回答您更一般的问题,以下是一些关于何时使用类型类以及何时不使用它们的经验法则:

    在以下情况下使用类型类:

    • 每个给定类型只有一个正确的行为

    • 类型类具有所有实例必须满足的相关方程(即“定律”)

    在以下情况下不要使用类型类:

    • 您正在尝试仅命名事物。这就是模块和命名空间的用途。

    • 如果不查看实例的源代码,使用您的类型类的人无法推断其行为方式

    • 您发现必须打开的扩展程序失控

    【讨论】:

    • 是的!这是一个非常完整的答案,非常感谢!您的“如果...不要使用类型类”将特别有助于选择做某事的好方法。
    • 我想补充一下“不要只为一种方法使用类型类”,尽管这不是一个绝对严格的规则,更像是一个一般性提示。
    • @MathematicalOrchid 这是“需要法则”规则的一部分,因为您很少有针对只有一种方法的类型类的法则(除了 SemiGroup 之类的方法,您可以在其中使用结合律)
    • 我觉得这个答案并不能真正解释为什么这些都是坏的或好的。它只是将其陈述为事实,没有任何解释我觉得这比没有答案更糟糕。
    【解决方案2】:

    您通常可以使用数据类型而不是类型类,例如

    data Repairable a = Repairable 
       { getRepairable :: a
       , isRepairable :: Bool
       , canBeRepairedWith :: [Tool] -> Bool  -- just to give an example of a function
       } 
    

    当然,您需要显式传递此值,但如果您有多种选择,这可能是一件好事(例如,将Sum 和Product 视为数字可能是Monoids)。除了你有或多或少与类型类相同的表现力。

    【讨论】:

    • 我不是反对者,但是 . . .这个答案并没有真正回答恕我直言的问题。 OP 询问何时应使用类型类。这个答案提到了类型类的替代方案,但没有说明何时使用该替代方案。 (如果有的话,它似乎预设了解类型类何时有意义,并提供了在许多相同情况下有意义的替代方案。)
    猜你喜欢
    • 2012-02-20
    • 2010-12-15
    • 1970-01-01
    • 2019-10-30
    • 2011-07-03
    • 2010-11-06
    • 2011-05-08
    • 2010-09-12
    • 2022-08-05
    相关资源
    最近更新 更多