首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >F#区分与可选递归组件的联合

F#区分与可选递归组件的联合
EN

Stack Overflow用户
提问于 2020-12-30 09:43:28
回答 3查看 88关注 0票数 1

我正在和F#合作,我很难建立我的商业模式。假设我有一个浮点列表和两种类型的转换,我可以在上面应用。举个例子:

类型转换=周期的_

然后,我定义了一个函数let compute Transformation list来计算列表上的任何类型的转换。

使用上面的转换类型,我可以通过示例创建一个SMA(3)或P2SMA(5)。

我希望能够以一种可以通过示例编写SMA(3,P2SMA(5,SMA(10))的方式嵌套转换。但我也希望仍然能够写SMA(2)只。我尝试使用选项,但我认为编写SMA(3,None)或SMA(3,一些(P2SMA(5)过于冗长。

有什么办法吗?也许我的方法是错误的,因为我是F#的新手,我可能用错误的方法来解决这个问题?

非常感谢你的帮助

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-12-30 15:22:27

在这里试试我的答案。

不可能以你想要的方式使受歧视的工会案件过载。但是,如果您要接受一个稍微不同的语法,您可以这样做:

代码语言:javascript
复制
type Period = int

type SmaTransform =
    | Sma of Period
    | Sma' of Period * Transform

and P2smaTransform =
    | P2sma of Period
    | P2sma' of Period * Transform

and Transform =
    | OfSma of SmaTransform
    | OfP2Sma of P2smaTransform

let SMA(period) =
    Sma(period) |> OfSma

let SMA'(period, transform) =
    Sma'(period, transform) |> OfSma

let P2SMA(period) =
    P2sma(period) |> OfP2Sma

let P2SMA'(period, transform) =
    P2sma'(period, transform) |> OfP2Sma

let transforms =
    [|
        SMA(3)
        P2SMA(5)
        SMA'(3, P2SMA'(5, SMA(10)))
    |]

for transform in transforms do
    printfn "%A" transform

与您想要的语法唯一不同的是表示嵌套转换的撇号。

票数 3
EN

Stack Overflow用户

发布于 2020-12-30 10:15:44

我尝试使用选项,但我认为编写SMA(3,None)或SMA(3,一些(P2SMA(5)过于冗长。

可以使用带有可选参数的静态成员:

代码语言:javascript
复制
type Transformation =
    | [<EditorBrowsable(EditorBrowsableState.Never)>]
      SMAInternal of period:int * inner: Transformation option
    ...
    static member SMA(period:int, ?t:Transformation) =
        SMAInternal(period, t)

然后您可以编写:Transformation.SMA(3)Transformation.SMA(3, Transformation.P2SMA(5))。这需要更多的字符,但构造更少。你可能认为它更简洁,也可能不认为它更简洁。

我是F#的新手,我可能会用错误的方法来解决这个问题?

如果要在代码文件中定义数百个这样的东西,那么使用上述方法并缩短名称Transformation可能是个好主意。否则就用索姆斯和诺恩斯。详细是一个微不足道的考虑,如果你开始担心它,可怕的事情开始发生。

票数 2
EN

Stack Overflow用户

发布于 2020-12-30 11:07:16

我不太明白你想要做什么,但我希望这里有一些相似的东西。

我的转换要么是多个数字,要么是添加到其中。

代码语言:javascript
复制
type Trans = 
    | Mult of period: int
    | Add of period: int

现在,我可以编写一个解释函数,给出一个数字和一个转换,我可以解释它。

代码语言:javascript
复制
let interpret x trans = 
    match trans with
    | Mult p -> p * x
    | Add p -> p + x

所以我们现在可以简单地让x=解释1 (Mult 2)

但是你想要链式转换吗?所以让我们允许..。

代码语言:javascript
复制
let interprets xs x = 
    List.fold (fun state trans -> 
        interpret state trans) x xs

我们可以去..。

代码语言:javascript
复制
let foo = [ Mult 3; Add 2 ]

let bar = interprets foo 1

好的,如果您真的想要统一处理这些转换列表的组合,这可能很好(有点像函数组合)。

然后,我会忍不住去(注意,我正在尝试遵循您的编码风格)(这里有很多东西要考虑,所以也许继续使用上面的方法,直到您满意地更好地理解F#为止)。

代码语言:javascript
复制
type Trans = 
    | Mult of period: int
    | Add of period: int
    | Compose of chain: List<Trans>
 
let rec interpret x trans = 
    let interprets xs x = 
        List.fold (fun state trans -> 
            interpret state trans) x xs
    match trans with
    | Mult p -> p * x
    | Add p -> p + x
    | Compose ps -> 
        interprets ps x
        
let two = interpret 1 (Mult 2)

let three = interpret 1 (Compose [ Mult 2; Add 1 ])

现在,我认为您有一个“工作”的数据模型,并且非常简单。

然后,我不会试图更改数据模型以使代码更方便,我会创建实用函数来实现这一点(智能构造函数)。

例如:

代码语言:javascript
复制
let multThen x trans = Compose [ Mult x; trans ]
let addThen x trans = Compose [ Add x; trans ]

不过,建议是使数据模型以最简单的方式对数据建模,然后使用函数使代码变得优雅,并在该模型中来回映射,这两件事通常看起来非常不同。

警告:我还没有测试过一些代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65504887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档