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