首页 > 解决方案 > 联合中的公共参数

问题描述

嗨 FSharpers(或任何 MLer)

仍在努力提高我的领域建模技能(来自 OOP)。假设我有以下

type A =
| AA of AA
| AB of AB

type AA = 
{ Code : 'a
  Time : 'b }

type AB =
{ Code : 'a
  Whatsoever : 'c }

现在让我们假设我想要以下函数签名: (A -> 'a)

据我目前的理解,我的解决方案是:

let f (a1:A) =
    match a1 with
    | AA a -> a.Code
    | AB a -> a.Code

这个解决方案的不便之处在于,如果我要向 A 联合添加一些新案例,它需要我总是在我的匹配中添加新案例。

我想另一种解决方案是元组类型的解决方案(但丢失了该字段的“命名”):

type A =
| AA of AA * 'a
| AB of AB * 'a

type AA = 
{ Time : 'b }

type AB =
{ Whatsoever : 'c }

let f (a1:A) =
    snd a1

有没有我错过的简单解决方案?谢谢!

标签: f#ml

解决方案


这:

let f (a1:A) =  snd a1

行不通,因为要到达元组,您首先需要匹配AAand AB

这可以工作:

type A0<'b, 'c> =
| AA of AA<'b>
| AB of AB<'c>

type A<'a, 'b, 'c> = A0<'b, 'c> * 'a

let f (a1:A<_,_,_>) =
    snd a1

您的解决方案Tmp<_>等同于使用元组。

顺便说一句,在 F# 中元素的顺序很重要,为了访问 typeAA它需要在 type 之前声明A。您的第一个示例应如下所示:

type AA<'a, 'b> = {
  Code : 'a
  Time : 'b }

type AB<'a, 'c> = {
  Code : 'a
  Whatsoever : 'c }

type A<'a, 'b, 'c> =
| AA of AA<'a, 'b>
| AB of AB<'a, 'c>

let f (a1:A<_,_,_>) =
    match a1 with
    | AA a -> a.Code

还要使用泛型参数,'a或者'b它们需要在顶部声明:

type A<'a, 'b, 'c> = ...

推荐阅读