加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

相当于Scala“案例类”在F#

发布时间:2020-12-16 09:37:56 所属栏目:安全 来源:网络整理
导读:我正在寻找在Scala中提供的“案例类”的F#中的等效项。 如果您想使用方法和字段创建自定义类,并且仍然可以使用模式匹配使用案例类,如Scala网站的此article中所述。 有没有人知道F#中是否存在相同? 解决方法 正如Brian所说,模式匹配有两种方式:1.现有类
我正在寻找在Scala中提供的“案例类”的F#中的等效项。

如果您想使用方法和字段创建自定义类,并且仍然可以使用模式匹配使用案例类,如Scala网站的此article中所述。

有没有人知道F#中是否存在相同?

解决方法

正如Brian所说,模式匹配有两种方式:1.现有类型的歧视工会和活动模式。

我们从这个Scala的例子开始:

abstract class Term
case class Var(name: String) extends Term
case class Fun(arg: String,body: Term) extends Term
case class App(f: Term,v: Term) extends Term

这个OO设计可以翻译成F#中的歧视联盟(DU):

type Term = 
    Var of string 
    | Fun of string * Term 
    | App of Term * Term

基于这个DU,您可以匹配一个Term值来查找它是什么子类型:

let eval (t: Term) = 
    match t with
    | Var (name) -> ...
    | Fun (para,body) -> ...
    | App (t1,t2) -> ...

请注意,您可以在此术语类型上定义方法和属性:

type Term = 
    Var of string 
    | Fun of string * Term 
    | App of Term * Term
    with 
    member x.Type() = 
        match x with
        | Var _ -> 0
        | Fun _ -> 1
        | App _ -> 2

现在这里有区别:

>您无法在其子类型上定义方法:Var,Fun和App。
>您可以在Term上定义的方法是不可变的。
>定义后不能扩展DU。想想你现在需要添加一个For子类型到Term。那么你必须改变很多代码,其中一个术语是模式匹配的。
>而在oo设计中,这不是一个问题。因为新的子类型可以承载自己的实现。

在F#中,当您要在子类型上构建简洁类型匹配时,应先考虑DU。但也有明显的限制。我认为活动模式匹配比Scala中的case类更加等同(我只读了一点Scala):

// define the classes for different term types
[<AbstractClass>]
type Term() = 
    abstract Value: int with get

type Var(name:string) =
    inherit Term()
    override x.Value = 
        0
    member x.Name with get() = name

type Fun(name:string,body:Term) = 
    inherit Term()
    override x.Value = 
        0
    member x.Name with get() = name
    member x.Body with get() = body


type App(t1:Term,t2:Term) = 
    inherit Term()
    override x.Value = 
        0    
    member x.Term1 with get() = t1
    member x.Term2 with get() = t2

// the pattern function 
let (|TVar|TFun|TApp|) (x:Term) = 
    match x with
    | :? Var -> 
        let y = x :?> Var
        TVar(y.Name)
    | :? Fun -> 
        let y = x :?> Fun
        TFun(y.Name,y.Body)
    | :? App ->
        let y = x :?> App
        TApp(y.Term1,y.Term2)

和使用活动模式的eval函数:

let eval2 (t:Term) = 
    match t with
    | TVar (name) -> 0
    | TFun (name,body) -> 0
    | TApp (t1,t2) -> 0

活动图案结合了两方面的优点:功能性编程和面向对象。

REF。 here和here活动模式。

Don Syme可以进一步参考the original paper on active pattern。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读