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
从概念上讲,为F#和C的任命创建一个歧视性的工会#_F#_Discriminated Union - Fatal编程技术网

从概念上讲,为F#和C的任命创建一个歧视性的工会#

从概念上讲,为F#和C的任命创建一个歧视性的工会#,f#,discriminated-union,F#,Discriminated Union,好心点,我对F(来自C)是个十足的新手。在查看我的约会簿的用户控件时,我看到它是建立在用于填充数据网格的“访问”类概念之上的。我想用一个F#descriminated并集来代替C#Visit类,但无法正确使用它。读了很多书之后,我似乎无法改变我的C语言思维 从概念上讲,“拜访”总是有一个“预约时间”,不管它有名字或其他什么。现在,从这一点来看,一次访问可以是几件不同的事情(使用歧视工会的原因): 如果访问只有姓名和发布时间,则仅为预约 如果访问只有预约时间、服务时间和姓名,那么该人在这里没有预约

好心点,我对F(来自C)是个十足的新手。在查看我的约会簿的用户控件时,我看到它是建立在用于填充数据网格的“访问”类概念之上的。我想用一个F#descriminated并集来代替C#Visit类,但无法正确使用它。读了很多书之后,我似乎无法改变我的C语言思维

从概念上讲,“拜访”总是有一个“预约时间”,不管它有名字或其他什么。现在,从这一点来看,一次访问可以是几件不同的事情(使用歧视工会的原因):

  • 如果访问只有姓名和发布时间,则仅为预约
  • 如果访问只有预约时间、服务时间和姓名,那么该人在这里没有预约,是一个“预约者”
  • 如果访问有姓名、预约时间、发布时间和服务时间,则该人所看到的是一个预约——“保留的预约”
  • 如果访问只有一个预约时间,没有名字或其他任何东西,那么它可以使用——“开放时间段”
  • 在C#中,这是一个简单的类:

    public class Visit
    {
       DateTime? tservice {get; set;}
       DateTime? tappointment {get; set;}
       DateTime? tposted {get; set; }
       string lastname {get; set; }
       string firstname {get; set; }
       DateTime birthdate {get; set; }
    }
    
    在F#中,这如何在概念上被写成一个有区别的联合体?我如何使用match…和它一起使用

    非常感谢任何帮助或指导。

    这是一个如何将其建模为F#中的联合的示例

    基本的想法是你已经描述了每个案例,我刚刚翻译了你口述的每个案例。每个案例都只允许使用数据,因此不存在可以填充或不填充的空值。除此之外,我还定义了一个helper成员,可以从任何形式的DU访问该成员以检索常用数据(就像我想象的那样)


    希望这有帮助

    该解决方案与切斯特胡斯克的类似,但有一些不同之处:

  • 由于约会时间总是存在,我认为将其移出DU是有意义的。因此,
    Visit
    是由
    visitType
    appointmentTime
    组成的记录
  • this.Name
    中,我们使用命名DU的一个功能,它允许我们只捕获所需的字段。这种形式更好,因为它对字段的顺序或数量是不变的

  • 我认为最好将
    Visit
    记录为
    appointmentTime
    vititType
    ,其中
    visitType
    是一个DU。考虑到这几个字段,我不同意。不同的案例清楚地模拟了不同的状态,完全捕获了每个字段的数据。这是f#的惯用用法,它与C#/Java非常不同。旗标/状态样式的枚举在我看来基本上是无用的。命名的析构主义的很好的使用:thumbsup:我认为对于一个简单的例子来说不值得这么做,但展示多种方式是很好的。谢谢!只是我记得在F#2.0中,即使是在稍微复杂的情况下(本质上,你总是必须记住完整的定义),所有这些匹配都是多么痛苦,所以我真的很兴奋能够像这样解构。@Dmitry Umm。。。什么是“DU”?DU=被歧视Uniion@Dmitry在我的预约簿的下一部分将访问记录扩展为从数据库读取的另一个更大的记录时,我很欣赏能够排除不必要的字段。但是,同样的约束也将适用。我还感谢使用选项,因为还需要使用错误控制。谢谢
    open System
    
    type VisitType = 
        | AppointmentOnly of name: string * postedTime: DateTime
        | WalkIn of name: string * serviceTime: DateTime
        | Kept of name: string * postedTime: DateTime * serviceTime: DateTime
        | Open
    
    type Visit =
        { appointmentTime: DateTime
          visitType: VisitType }
    with
        member this.Name =
            match this.visitType with
            | AppointmentOnly(name=name) | WalkIn(name=name) | Kept(name=name) -> Some name
            | Open -> None
    
    let visit = { appointmentTime = DateTime.Now
                  visitType = WalkIn(name="cool_name", serviceTime=DateTime.Now) }
    
    printfn "%A" visit.Name
    printfn "%A" visit.appointmentTime