首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >"Unbox“--多才多艺的歧视结合/寻找好的解决办法

"Unbox“--多才多艺的歧视结合/寻找好的解决办法
EN

Stack Overflow用户
提问于 2011-10-30 16:13:52
回答 2查看 288关注 0票数 0

对于一个小型AST解析器,我有一个小的受歧视的联合

代码语言:javascript
复制
type Numerical =
    | Int of int
    | Real of float

在其他构造中使用,如

代码语言:javascript
复制
type Vector = Numerical list
Vector [Int 42; Real 13.5]

当我有了这样的方法

代码语言:javascript
复制
let eval (e:Numerical) =
    match e with
    | Int n -> ... (* return int *)
    | Real r -> ... (* return float *)

我知道F#推断int类型并在第二行中用Real模式生成一个错误,所以我想知道哪种代码设计是能够处理这种“泛型”类型并用给定类型返回其适当值的最佳代码。

编辑

这里有一个或者的情况,它会导致类似的函数

代码语言:javascript
复制
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 42Real 13. )和原始数据类型来真正运行计算,但能够返回适当的包装器。如果我想要添加Real 1.Real 1.5,我想提取1.0 + 1.5 = 2.5,然后继续使用Real 2.5,但是我不想把所有的东西都作为浮点数来处理,这样就可以区分ints和floats。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-30 16:50:15

您可以将结果转换为obj

代码语言:javascript
复制
let eval (e:Numerical) =
    match e with
    | Int n -> n :> obj
    | Real r -> r :> obj

但这可能不是你想要的。

另一个选择是在Numerical上实现您自己的操作。

代码语言:javascript
复制
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"

不能有基于某些运行时值具有不同编译时返回类型的函数。

票数 3
EN

Stack Overflow用户

发布于 2011-10-30 21:57:25

代码语言:javascript
复制
let eval<'T> (e:Numerical):'T =
    match e with
    | Int n -> n :> obj :?> 'T
    | Real r -> r :> obj :?> 'T

演示

代码语言:javascript
复制
> 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 typemismatch
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7946096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档