我是Haskell的新手,我正在尝试为家庭作业实施计算器。我被困在一个需要对两个值进行除法的地方,我认为问题在于它们的类型无法推断或需要声明/转换。我正在努力学习如何解决这个问题,但是在此过程中的任何见解都会有所帮助。
以下是代码:
data Value e = OK e | Error String deriving (Eq)
-- assuming we know how to type e can be shown, i.e. Show e, then
-- we know how to show a Value e type
instance (Show e) => Show (Value e) where
show (OK x) = (show x)
show (Error s) = "ERROR: " ++ s
type Token = String
type Result = Value Int
type Intermediate = [ (Value Int) ]
-- an algebra is a things that knows about plus and times
class Algebra a where
plus :: a -> a -> a
times :: a -> a -> a
subtraction :: a -> a -> a
division :: a -> a-> a
-- assuming that we know how to + and * things of type e, (i.e.
-- we have Num e, then we have algebra's over Value e
instance (Num e) => Algebra (Value e) where
plus (OK x) (OK y) = (OK (x+y))
times (OK x) (OK y) = (OK (x*y))
subtraction (OK x) (OK y) = (OK (x-y))
division (OK x) (OK 0) = (Error "div by 0")
division (OK x) (OK y) = (OK (x `div` y)) <-- this is line 44 that it complains about
当我尝试通过ghci test.hs
运行程序时出现错误test.hs:44:34:
Could not deduce (Integral e)
from the context (Algebra (Value e), Num e)
arising from a use of `div' at test.hs:44:34-42
Possible fix:
add (Integral e) to the context of the instance declaration
In the first argument of `OK', namely `(x `div` y)'
In the expression: (OK (x `div` y))
In the definition of `division':
division (OK x) (OK y) = (OK (x `div` y))
还有更多的代码,我想我会把它留下来以保持清晰,但如果不清楚我可以随时编辑它。
答案 0 :(得分:8)
div :: (Integral a) => a -> a -> a
(/) :: (Fractional a) => a -> a -> a
Num a
并不意味着Integral a
或Fractional a
(当然,反过来也适用)。如果您想使用div
,则必须提供至少与Integral a
上下文一样严格的内容。
答案 1 :(得分:3)
div
仅对Integral
个值(标准前奏中仅Int
或Integer
)起作用。 Float
和Double
支持/
运算符的除法,但问题的根源是Num
类型类实际上并不强制执行任何类型的除法运算。< / p>
这是有道理的 - 我们可能想要制作Num
实例的大量数字集合,其中乘法是不可逆的 - 除法运算本质上是没有意义的。