gpt4 book ai didi

scala - 与F#中的Scala “case class”等效

转载 作者:行者123 更新时间:2023-12-03 11:52:27 26 4
gpt4 key购买 nike

我正在寻找Scala中可用的F#中的“案例类”中的等效项。

当您想使用方法和字段创建自定义类并且仍然能够将它们与模式匹配一​​起使用时,案例类非常有用,如Scala网站的此article中所述。

有谁知道F#中是否存在相同的东西?

最佳答案

正如Brian提到的,模式匹配有两种方法:1.区分联合和2.在现有类型上使用 Activity 模式。

让我们从这个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) -> ...

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

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

现在来了区别:
  • 您不能在其子类型上定义方法:VarFunApp
  • 您可以在Term上定义的方法是不可变的。
  • 一旦定义了DU,就不可能对其进行扩展。想想您现在需要向For添加Term子类型。然后,您必须更改Term与模式匹配的许多代码。
  • 在oo设计中,这不是问题。因为新的子类型可以带有自己的实现。

  • 在F#中,当您要在子类型上构建简洁类型匹配时,应首先考虑DU。但这也有明显的限制。我认为 Activity 模式匹配更类似于Scala中的案例类(我只读了一点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)

    以及使用 Activity 模式的 eval函数:

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

    Activity 模式结合了双方的优点:函数式编程和面向对象。

    引用 herehere用于 Activity 模式。

    您可以进一步引用Don Syme的 the original paper on active pattern

    关于scala - 与F#中的Scala “case class”等效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6354863/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com