我应该使用typeclasses或不?
我在使用时以及在代码中不使用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代码而不是只定义函数时,我经常看到类似这样的东西(新数据类型+ typeclasses +实例)。
所以,当我应该创建新的数据类型,类型类等,我应该什么时候使用函数?
谢谢。
为什么我不应该做一些简单的事情,只定义函数而不定义新的数据类型和类型类(使用它们的实例)。
为什么呢? 你可以定义:
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
人们总是滥用类型课程。 这并不意味着它是惯用的。
为了回答你更一般的问题,下面是关于何时使用类型类以及何时不使用类的一些经验法则:
使用类型类如果:
每种给定类型只有一个正确的行为
类型类具有所有实例必须满足的关联方程(即“法则”)
在下列情况下不要使用类型类:
你正试图命名空间的东西。 这就是模块和名称空间的用途。
使用你的类型类的人不能在没有查看实例的源代码的情况下推断它的行为
您发现您必须启用的扩展程序已经失控
您可以经常使用数据类型而不是类型类,例如
data Repairable a = Repairable
{ getRepairable :: a
, isRepairable :: Bool
, canBeRepairedWith :: [Tool] -> Bool -- just to give an example of a function
}
当然,你需要明确地传递这个值,但如果你有多个选择,这可能是一件好事(例如,认为Sum
和Product
可能是Monoid
)。 除了你的表现力与类型类别差不多。
上一篇: Should I use typeclasses or not?
下一篇: Creating many similar newtypes/typeclass instances in Haskell