> For the complete documentation index, see [llms.txt](https://kurohasu.gitbook.io/fsharpabout/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kurohasu.gitbook.io/fsharpabout/advance/rekdoto.md).

# レコードと共用体

### レコードについて

レコードは名前付きの値の集合体で、任意でメンバーを含ませることが出来ます。\
(オブジェクト指向と関連しているためこちらも参考になるかもしれません)

```
構文:type レコード型名=
    {
        定数名1:データ型
        定数名2:データ型
        ...
    }
    member this.メソッド(<引数>)=
        処理...

定義:
    let 変数名:レコード型名={定数名1=<値>;定数名2=<値>;...}
    
メンバー呼び出し:
    変数名.メソッド(<引数>)
```

{% hint style="info" %}
レコードの宣言時にmutableをつけると変数として登録できます\
また定義時にレコード型名を指定することで他のレコード型との混合を回避できます
{% endhint %}

### 匿名レコード

匿名レコードは通常のレコードと異なり、ただ名前付きの値を集めたものです\
わざわざ宣言する必要はないけどレコードを作成したいときに便利です

```
構文:let 関数名(<引数>)=
    処理...
    {|要素名1=値1;要素名2=値2;...|}
```

### コピーと更新

既存のレコード・匿名レコードの値をコピーし新しいレコードの作成を行うことが出来ます

```
構文:
    {既存レコード with 定数名1=新値1;定数名2=新値2;...}
    {|既存匿名レコード with 定数名1=新値1;定数名2=新値2;...|}
```

```fsharp
//例:PGレコード"FSharp"を元に"QSharp"レコードを作成する
type PG=
    {
        language:string
        typelang:string
        developer:string
    }
    member this.outdetail()=printfn "lang=%s,type=%s,dev=%s" this.language this.typelang this.developer

//定義
let FSharp:PG={language="F#";typelang="Functional";developer="MicroSoft"}
let QSharp={FSharp with language="Q#";typelang="Quantum"}
//↑FSharpレコードを元に、languageとtypelangを変える

//確認
FSharp.outdetail()
QSharp.outdetail()


//出力
//lang=F#,type=Functional,dev=MicroSoft
//lang=Q#,type=Quantum,dev=MicroSoft

```

### 判別共用体

判別共用体は値に対する任意の型の候補を複数定義したものを集めたものです\
成功・失敗時のデータや特殊なデータの判断などに活用できます

```
構文:type 共用体名=
        |型名1 of データ名A1:データ型 * データ名B1:データ型 * ... 
        |型名2 of データ名A2:データ型 * データ名B2:データ型 * ... 
        ...
```

サンプルの例を元に判別共用体を考えてみましょう

```fsharp
//Shapeの定義
type Shape =
    | Rectangle of width : float * length : float
    | Circle of radius : float
    | Prism of width : float * float * height : float

//各型を宣言してみる
let rect = Rectangle(length = 1.3, width = 10.0)
let circ = Circle (1.0)
let prism = Prism(5., 2.0, height = 3.0)
```

1行目のrectはRectangle型,2行目のcircはCircle型,3行目のprismはPrism型を用いて値を割り当てていますが、ShapeのPrismの定義に注目すると"width:float\*float\*height:float"となっています\
これはwidthとheightが名前付きフィールドであり、第２引数の「2.0」は匿名レコードとなっています\
またmatch文を使って型の判断を行うことが出来ます

```fsharp
//それぞれの型を判断し長さを返すgetShapeWidth関数
let getShapeWidth(shape)=
    match shape with
    | Rectangle(width = w) -> w
    | Circle(radius = r) -> 2. * r
    | Prism(width = w) -> w
```

{% hint style="info" %}
レコードも判別共用体もF#を強力にする機能です。\
使いこなせるようになるとより高度な開発が行えるかもしれません:)
{% endhint %}
