我可以像这样创建一个Num a => a
:
foo :: Num a => a
foo = 2
对于任何其他数字类别:
foo :: Fractional a => a
foo = 2.0
但是,我无法想出一种创建Eq a => a
,Ord a => a
类型或任何非数字(不使用undefined
)的方法。
在我看来,数字在这方面很特别。
是吗?
答案 0 :(得分:6)
Num
在某种意义上并不是“特殊的”,因为它是这种行为的唯一方式。但它确实具有一些使其成为可能的特征。请考虑使用Bounded
类型类。完全可以定义类似的功能:
top :: Bounded a => a
top = maxBound
这是可能的,因为Bounded
与Num
不同,但与Eq
不同,它提供了一种创建其类型值的方法。
答案 1 :(得分:5)
还有更多例子:
def :: Default a => a
mempty :: Monoid a => a
maxBound :: Bounded a => a
toEnum 0 :: Enum a => a
read "" :: Read a => a
fromString "" :: IsString a => a
这只是我的头脑。我相信还有更多。
答案 2 :(得分:1)
Num
的特殊之处在于它具有编写文字的特殊语法。此语法在内部使用函数fromInteger :: Num a => Integer -> a
,该函数在Num
中定义。编译器将您编写的内容解析为Integer
,并将其提供给fromInteger
以获取您看到的类型。
你不能用例如Eq a => a
执行此操作的原因是Eq
中没有返回该类型内容的函数。
如果你确实需要这样的值,你可以使用ExistentialQuantification扩展来使用类似data Equatable = forall e. Eq e => MkEquatable e
的东西,但这可能不是你想要做的。
以下是您可以为其创建类型为MyClass a => a
的值的类型类示例:gist