相当于Scala“案例类”在F#
我正在寻找在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。 在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。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |