由于lambda演算,Haskell比许多语言更具数学性,但我认为这些域的数字不完整:例如,我们有Integer
和Float
但不是Positive
或Negative
或[1..5]
作为域名。
这有时会使函数不安全,而编译器可能会捕获类型错误。例如:5
mod 0
仅在运行时输出*** Exception: divide by zero
。
mod :: Integral a => a -> a -> a
但我们可以拥有类似mod :: Integral a, a != 0 => a -> a -> a
的内容;像守卫或间隔或其他数据类型的东西......在游戏中,我希望我的角色有一个正数的生命。或者从0到100,不是在下,而不是在上。当他被击中时,我需要打电话给丑陋的positive x = if x > 0 then x else 0
。即使C有signed
和unsigned
。
这是一个弱点还是他们为什么没有“间隔”域名的原因?有没有一个包修复这个?
答案 0 :(得分:6)
听起来你正在寻找一种依赖类型的语言,如Agda,Idris或Coq。
你是对的,拥有受限制的数字类型会很好,但你需要考虑如何使用这些类型。假设您的mod
类型排除了0
值。现在你需要在你的程序中调用它。如果数字是文字,大概是编译器确定它不是0
并且让你调用函数“很容易”,但是如果数字是在运行时提供的,可能来自用户输入或某些复杂程序?您需要一些方法向编译器解释,当您将其传递给0
时,您知道该数字不会是mod
。 Haskell并没有真正有能力以任何简单的方式做到这一点(有很多令人讨厌的方法,比如将所有值反映到类型系统中),这就是为什么你看不到更精确的类型。
答案 1 :(得分:6)
你可以自由地开设这样的课程,但也许他们之所以没有被纳入Haskell,是因为人们无法找到让他们经常的方法是有用的。
很明显,你想要与你的班级相减,但你也希望它被关闭。
这样的事可能吗?
NonNegative x - NonNegative y = NonNegative (max (x - y) 0)
但是身份x - y + y == x
不成立。
人们为Haskell制作了替代数字层次结构,例如'Numeric Prelude'。 Haskell对自定义非常友好,你甚至可以用你自己的定义替换Prelude,但是它们是否有用并且不会导致比它们解决的问题更多的问题。