对于一个小型AST解析器,我有一个小的受歧视的联合
type Numerical =
| Int of int
| Real of float在其他构造中使用,如
type Vector = Numerical list
Vector [Int 42; Real 13.5]当我有了这样的方法
let eval (e:Numerical) =
match e with
| Int n -> ... (* return int *)
| Real r -> ... (* return float *)我知道F#推断int类型并在第二行中用Real模式生成一个错误,所以我想知道哪种代码设计是能够处理这种“泛型”类型并用给定类型返回其适当值的最佳代码。
编辑
这里有一个或者的情况,它会导致类似的函数
let getInt = function
| Int n -> n
| Real _ -> failwith "Given value doesn't represent an int"
let getReal = function
| Real n -> n
| Int _ -> failwith "Given value doesn't represent a real number"但是,我想要一种封装两种情况并“自动选择正确的情况”的方法。
这一努力应该导致能够使用“装箱”值(如Int 42和Real 13. )和原始数据类型来真正运行计算,但能够返回适当的包装器。如果我想要添加Real 1.和Real 1.5,我想提取1.0 + 1.5 = 2.5,然后继续使用Real 2.5,但是我不想把所有的东西都作为浮点数来处理,这样就可以区分ints和floats。
发布于 2011-10-30 16:50:15
您可以将结果转换为obj
let eval (e:Numerical) =
match e with
| Int n -> n :> obj
| Real r -> r :> obj但这可能不是你想要的。
另一个选择是在Numerical上实现您自己的操作。
let (+) a b =
match (a,b) with
| (Int an, Int bn) -> Int (an + bn)
| (Real ar, Real br) -> Real (ar + br)
| _ -> failwith "Can't add Int and Real"不能有基于某些运行时值具有不同编译时返回类型的函数。
发布于 2011-10-30 21:57:25
let eval<'T> (e:Numerical):'T =
match e with
| Int n -> n :> obj :?> 'T
| Real r -> r :> obj :?> 'T演示
> eval<float>(Real 4.5);;
val it : float = 4.5
> eval<int>(Int 42);;
val it : int = 42
> let x:float = eval (Real 5.5);;
val x : float = 5.5
> let x:int = eval (Real 5.5);;//NG typemismatchhttps://stackoverflow.com/questions/7946096
复制相似问题