Haskell 函数的模式匹配 (+) (-) (/) (*)
Haskell Pattern Matching for fuctions (+) (-) (/) (*)
对于函数定义,我需要在检测到被零除时输出错误。
一般情况如下,op
取(+),(-),(*),(/)函数。
liftIntOp :: (Int->Int->Int)->Val->Val->Val
liftIntOp op (IntVal a) (IntVal b) =IntVal $ op a b
用例是
Main>liftIntOp (+) (IntVal 3) (IntVal 5)
Main>IntVal 8
但是我尝试检测除以 0 的特殊情况。我的解决方案是
liftIntOp :: (Int->Int->Int)->Val->Val->Val
liftIntOp (/) _ (IntVal 0) =ErrorVal "Division by 0"
liftIntOp op (IntVal a) (IntVal b) =IntVal $ op a b
但第一个分支似乎匹配任何运算符。
Main> liftIntOp (-) (IntVal 3) (IntVal 0)
Main> ErrorVal "Division by 0"
Main> liftIntOp (+) (IntVal 3) (IntVal 0)
Main> ErrorVal "Division by 0"
不知如何挑出除法的案例
首先,你在 (/)
上的模式匹配不起作用,因为 GHC 认为你想将该参数绑定到名称 (/)
并覆盖 (/)
的通常绑定。看这个更简单的例子:
ghci> let foo (/) x y = x / y
ghci> foo (+) 1 2
3
正如 Willem Van Onsem 在评论中指出的那样,处理此问题的常用方法是引入要匹配的所有函数的枚举数据类型:
data Operation = Add | Sub | Mul | Div
此外,您还需要为这些操作赋予语义(意义):
applyIntOp :: Operation -> Int -> Int -> Int
applyIntOp Add = (+)
applyIntOp Sub = (-)
applyIntOp Mul = (*)
applyIntOp Div = div -- note that (/) doesn't work on Int
那么你可以定义liftIntOp
为:
liftIntOp :: Operation -> Val -> Val -> Val
liftIntOp Div _ (IntVal 0) = ErrorVal "Division by zero"
liftIntOp op (IntVal x) (IntVal y) = IntVal (applyIntOp op x y)
对于函数定义,我需要在检测到被零除时输出错误。
一般情况如下,op
取(+),(-),(*),(/)函数。
liftIntOp :: (Int->Int->Int)->Val->Val->Val
liftIntOp op (IntVal a) (IntVal b) =IntVal $ op a b
用例是
Main>liftIntOp (+) (IntVal 3) (IntVal 5)
Main>IntVal 8
但是我尝试检测除以 0 的特殊情况。我的解决方案是
liftIntOp :: (Int->Int->Int)->Val->Val->Val
liftIntOp (/) _ (IntVal 0) =ErrorVal "Division by 0"
liftIntOp op (IntVal a) (IntVal b) =IntVal $ op a b
但第一个分支似乎匹配任何运算符。
Main> liftIntOp (-) (IntVal 3) (IntVal 0)
Main> ErrorVal "Division by 0"
Main> liftIntOp (+) (IntVal 3) (IntVal 0)
Main> ErrorVal "Division by 0"
不知如何挑出除法的案例
首先,你在 (/)
上的模式匹配不起作用,因为 GHC 认为你想将该参数绑定到名称 (/)
并覆盖 (/)
的通常绑定。看这个更简单的例子:
ghci> let foo (/) x y = x / y
ghci> foo (+) 1 2
3
正如 Willem Van Onsem 在评论中指出的那样,处理此问题的常用方法是引入要匹配的所有函数的枚举数据类型:
data Operation = Add | Sub | Mul | Div
此外,您还需要为这些操作赋予语义(意义):
applyIntOp :: Operation -> Int -> Int -> Int
applyIntOp Add = (+)
applyIntOp Sub = (-)
applyIntOp Mul = (*)
applyIntOp Div = div -- note that (/) doesn't work on Int
那么你可以定义liftIntOp
为:
liftIntOp :: Operation -> Val -> Val -> Val
liftIntOp Div _ (IntVal 0) = ErrorVal "Division by zero"
liftIntOp op (IntVal x) (IntVal y) = IntVal (applyIntOp op x y)