哈斯克尔.使用约束来定义类的实例

nyv*_*ken 4 haskell class instance

在尝试理解Haskell中的实例时,我做了这个例子.整数部分运行良好,但它不适用于Float实例.我认为最好制作Num类型的单个实例(这样正方形适用于所有Num).我想我必须添加Num作为我的类声明的约束,但我无法弄清楚实例的样子.据我了解,类的约束强制任何实例属于该类型(根据约束).

class Square a where
    area :: a -> a

instance Square Integer where
    area a = a*a

instance Square Float where
    area a = a*a
Run Code Online (Sandbox Code Playgroud)

lef*_*out 10

我认为最好制作一个类型的单个实例Num......

不是真的,除非你要定义一个类只能用于Num类型(然后你不需要一个类所有,只是让它area :: Num a => a->a作为一个顶级功能).

这是制作这样一个通用实例的方法:

instance (Num a) => Square a where
  area a = a*a
Run Code Online (Sandbox Code Playgroud)

这不是Haskell98,但它确实适用于广泛使用-XFlexibleInstances-XUndecidableInstances扩展.

问题:如果你还想添加,比方说,

instance Square String where
  area str = concat $ replicate (length str) str
Run Code Online (Sandbox Code Playgroud)

你有两个重叠的实例.这是一个问题:通常,编译器无法确定哪两个这样的实例是正确的.再次GHC有扩展,做出最好的猜测(-XOverlappingInstances-XIncoherentInstances),但与Flexible/UndecidableInstances这些通常避免.

因此,我建议做个别情况下Square Int,Square Integer,Square Double.他们不是很难写,不是吗?