我需要在类似下面的情况下使用静态解析的类型参数:
[<Struct>]
type Wrapper<'T> =
val raw:'T
new(v:'T) = {raw = v}
type Value =
| Float of float
| Int of int
| String of string
with
member this.ToWrapper() :'T =
match this with
| Float f -> Wrapper<float>(f) // type is inferred as float
| Int i -> Wrapper<int>(i) // error
| String s -> Wrapper<string>(s) // error
如何定义和使用可以映射&#39;值&#39;的ToWrapper函数(或其集合)。类型为Generic Wrapper中的任何类型&lt;&gt; T&gt;在哪里我知道&T将会浮动| int |字符串?
包装器&lt;&gt;&gt;类型需要是一个结构,因此接口不是一个选项 - 正如在与此相关的其他一些帖子中所建议的那样。
答案 0 :(得分:5)
我不清楚你想要达到什么目标。您是否尝试将包装类型限制为Int,String和Float?
1)如果是这样,你可以在运行时检查:
[<Struct>]
type Wrapper<'T> =
val raw:'T
new(v:'T) = {raw = v}
let wrap x =
match box x with
| :? float -> ()
| :? int -> ()
| :? string -> ()
| _ -> failwith "invalid type"
Wrapper x
let a = wrap 90
let b = wrap "hi"
let c = wrap true // fails at runtime
2)如果你想在编译时限制一个简单的方法是添加静态成员作为构造函数:
[<Struct>]
type Wrapper<'T> =
val raw:'T
private new(v:'T) = {raw = v}
with
static member wrap (x:float) = Wrapper x
static member wrap (x:int) = Wrapper x
static member wrap (x:string) = Wrapper x
let a = Wrapper<_>.wrap 90
let b = Wrapper<_>.wrap "hi"
let c = Wrapper<_>.wrap true // doesn't compile
3)或者可能是,使用包装内的DU对你来说更有意义:
type Value =
| Float of float
| Int of int
| String of string
[<Struct>]
type Wrapper =
val raw:Value
new(v:Value) = {raw = v}
在所有解决方案中3)是唯一一个真正限制你的包装器的解决方案。解决方案1)和2)限制你构建它的方式。
从2开始,您可以使用一些具有静态解析类型参数的技巧,以便提供仅包装在这些类型上的内联函数(不是方法)。仍然不会限制类型本身,但由于构造函数是私有的,因此使用类型的代码将被强制通过受限制的构造函数。
静态解析的类型参数可以使用函数或方法,但不能处理类型,因为它们是编译时F#特性,而不是.NET类型的系统特性。
答案 1 :(得分:2)
您无法执行此操作,因为Wrapper<float>
与Wrapper<int>
的类型不同(Wrapper<string>
的类型与ToWrapper
的类型不同) 。 <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Accommodation</a></li>
<li><a href="#">Services & Amenities</a></li>
<li><a href="#">Experience</a></li>
<li><a href="#">Media</a></li>
<li><a href="#">About</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
的返回类型是什么?它不可能同时全部三个。