簡體   English   中英

在F#中相當於Scala“案例類”

[英]Equivalent of Scala “case class” in F#

我正在尋找Scala中可用的F#中的“案例類”中的等效項。

當您想使用方法和字段創建自定義類並且仍然能夠將它們用於模式匹配時,案例類非常有用,如Scala網站上的文章所述。

誰知道F#中是否存在相同的東西?

正如Brian所提到的,模式匹配有兩種方法:1.區分聯合和2.在現有類型上使用活動模式。

讓我們從這個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

現在來了區別:

  1. 您不能在其子類型上定義方法: VarFunApp

  2. 您可以在Term上定義的方法是不可變的。

  3. 一旦定義了DU,就不可能對其進行擴展。 想想您現在需要為Term添加一個For子類型。 然后,您必須更改大量代碼,其中Term是模式匹配的。

  4. 而在oo設計中,這不是一個問題。 因為新的子類型可以帶有自己的實現。

在F#中,當您要在子類型上構建簡潔類型匹配時,應首先考慮DU。 但這也有明顯的限制。 我認為活動模式匹配更類似於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)

和使用活動模式的eval函數:

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

活動模式結合了雙方的優點:函數式編程和面向對象。

參考 這里這里的活動模式。

您可以進一步參考Don Syme撰寫的有關活動模式的原始論文

受歧視的工會? 您可以向其添加成員方法。 或者,您可以在現有的類上使用活動模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM