Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 如何访问在F中声明为泛型参数的类型的静态成员#_Generics_F#_Constraints - Fatal编程技术网

Generics 如何访问在F中声明为泛型参数的类型的静态成员#

Generics 如何访问在F中声明为泛型参数的类型的静态成员#,generics,f#,constraints,Generics,F#,Constraints,我想在F#中创建一个基类型,这将允许我使用预定义的约束简化其他类型的创建,即限制为非负整数等。。 我创建了以下基类型,它打算使用作为泛型参数提供的验证器类型的静态成员,希望我能够引用它的静态“条件”成员-不幸的是,我似乎无法引用类型正文中的任何地方的泛型^tf,更不用说它的静态成员了 type Constrained<^tf when ^tf:(static member Condition: 'tv->bool)> (value : int) = static

我想在F#中创建一个基类型,这将允许我使用预定义的约束简化其他类型的创建,即限制为非负整数等。。 我创建了以下基类型,它打算使用作为泛型参数提供的验证器类型的静态成员,希望我能够引用它的静态“条件”成员-不幸的是,我似乎无法引用类型正文中的任何地方的泛型^tf,更不用说它的静态成员了

  type Constrained<^tf when ^tf:(static member Condition: 'tv->bool)> (value : int) =
     static member Create (v) =             
        match ^tf.Condition v with
        | true -> Some ( Constrained(v) )
        | _ -> None

type constrated再次阅读您的问题后,我想您应该开始编写以下代码:

type T = T with
    static member Condition (x) = x > 0

type Constrained< ^tf when ^tf:(static member Condition: int->bool)> (value : int) =
    static member inline Create (v) =             
        match (^tf : (static member Condition : int->bool) v) with
        | true -> Some ( Constrained(v) )
        | _    -> None


let x:Constrained<T> option = Constrained<T>.Create(1)
类型T=T,带
静态构件条件(x)=x>0
当^tf:(静态成员条件:int->bool)>(值:int)时,类型受限<^tf=
静态成员内联创建(v)=
将(^tf:(静态成员条件:int->bool)v)与
|正确->某些(受约束的(v))
|无
设x:constrated option=constrated.Create(1)

但不确定这给你带来了什么。

这里有一种方法可以用DU而不是类来完成。这样做的好处是可以获得默认的结构相等

module Constrained =
    type Constrained< ^a when ^a : (member Condition : bool) > =
        private Constrained of ^a with
        static member inline Create (x:^a ) =
            if (^a : (member Condition : bool) x) then Some (Constrained x)
            else None
        member inline this.Value : ^a = match this with Constrained v -> v

type PosInt = PosInt of int with member this.Condition = this |> fun (PosInt x) -> x > 0
type NonEmptyString = NonEmptyString of string with member this.Condition = this |> fun (NonEmptyString x) -> x.Length > 0

open Constrained

Constrained.Create (PosInt -1) // None
Constrained.Create (NonEmptyString "") // None

(Constrained.Create (PosInt 1)) // Some (Constrained (PosInt 1))
(Constrained.Create (NonEmptyString "a")) // Some (Constrained (NonEmptyString "a"))

let f (x:Constrained<PosInt>) =
    match x.Value with PosInt i -> i + 1

Constrained (PosInt -1) // Compile error. The private union case constructor cannot be used outside of the Constrained module
模块约束=
当^a:(成员条件:bool)>=
带的^a的私有约束
静态成员内联创建(x:^a)=
如果(^a:(成员条件:bool)x)那么一些(受约束的x)
没有别的
成员内联此。值:^a=将此与受约束的v->v匹配
键入PosInt=PosInt of int,成员为this.Condition=this |>fun(PosInt x)->x>0
键入NonEmptyString=包含此成员的字符串的NonEmptyString.Condition=this |>fun(NonEmptyString x)->x.Length>0
开放约束
Constrained.Create(PosInt-1)//无
受限。创建(非空字符串“”)//无
(constrated.Create(PosInt 1))//一些(constrated(PosInt 1))
(constrated.Create(NonEmptyString“a”)//Some(constrated(NonEmptyString“a”))
设f(x:约束)=
将x.值与PosInt i->i+1匹配
约束(PosInt-1)//编译错误。私有联合事例构造函数不能在受约束模块之外使用

如果使用相同的约束,则可以使用类。请注意,不能在F#中写入
Foo
。该语法仅在以下空格中有效:
Foo<^a…>

您可以使用静态成员约束解决此问题,其他答案说明了如何解决此问题。然而,我想知道,与将条件视为普通函数相比,这是否会给您带来任何实际好处。例如,当您使用您的类型时,您必须编写如下内容:

Constrained<Conditions.NonNegative>.Create 42
静态成员约束没有问题,但它们是一种相当高级的语言特性,我非常喜欢保持简单,所以我只在真正需要时才使用它们。(如果愿意,使用函数可以使用部分应用程序。)

为完整起见,基于功能的版本应为:

type Constrained(value : int) =
    static member Create condition v =             
        match condition v with
        | true -> Some ( Constrained(v) )
        | _ -> None

module Conditions =
  let positive n = n > 0

Constrained.Create Conditions.positive 42

这不是静态解析成员的名称。看一看文档:@Gustavo,如果我未充分挖掘,我不是sue,但我正在尝试访问一个类型的静态成员,一个由约束保证的成员。我这样做不需要任何帮助。我的理解是“when^tf:(静态成员条件:'tv->bool)”与接口的工作方式相同-除非我完全弄错了…@MichalPawluk也许我误解了你。能否添加另一种类型的示例,即实现成员
条件的示例?@MichalPawluk我添加了一些代码作为答案,看一看,知道这是否是您要查找的。@Gustavo,当然,这样的类型看起来像,即类型ConstraintExample=静态成员条件(a:int)这正是我要找的。谢谢
type Constrained(value : int) =
    static member Create condition v =             
        match condition v with
        | true -> Some ( Constrained(v) )
        | _ -> None

module Conditions =
  let positive n = n > 0

Constrained.Create Conditions.positive 42