1
我有一个类型数值类型
data Value = Int Integer
| Float Double
| Complex (Complex Double)
| ... (other, non-numeric types)
与联营错误类型
data ValueError = TypeMismatch Value | ... (other constructors)
type ThrowsError = Either ValueError
,我想通过类型来实现通用的二进制运算,具有自动强制的最高类型的自动强制在一个操作数不是数值类型的情况下是错误信号,即函数
binaryOp :: Num a => (a -> a -> a) -> Value -> Value -> ThrowsError Value
这样我就可以写,例如,
(binaryOp (+)) (Int 1) (Int 1) ==> Right (Int 2)
(binaryOp (+)) (Int 1) (Float 1.0) ==> Right (Float 2.0)
(binaryOp (+)) (Int 1) (String "1") ==> Left (TypeMismatch (String "1"))
有没有一种简单的方法来做到这一点?我首先想到的是与功能
typeOf :: Value -> NumType
typeOf (Int _) = IntType
...
promote :: Value -> Value
promote (Int n) = Float (fromInteger n)
promote (Float n) = Complex (n :+ 0)
沿定义类似
data NumType = IntType | FloatType | ComplexType
,但我有困难,使其工作。有什么建议?
更多的上下文。我正在写一位计划翻译,我想实施计划numeric tower。
其实我是想实现的东西稍微比我解释更复杂,因为我希望适用于参数任意数量的东西,沿着这将与foldl1
实施的
binaryOp :: Num a => (a -> a -> a) -> [Value] -> ThrowsError Value
线,但我觉得如果我能解决更简单的问题,那么我就能解决这个更复杂的问题。
谢谢,我现在有一个基本的版本!这是StackOverflow最棒的例子。我甚至不知道你可以对函数的域进行存在量化(尽管现在我看到它似乎很明显......),所以我可能永远都不会自己发现它。 – 2012-04-18 20:35:33