删除F#中两个离散类型完全相同的重复代码

问题描述 投票:0回答:1

我有一个离散联合WordContainer,它要么是WordDocument 的Doc,要么是WordTableCell 的Cell。 就该特定功能而言,每种类型在功能方面都具有相同的 API。我是 使用匹配表达式来确定该值是 Doc 还是 Cell,然后在每个 使用两个不同变量的相同代码。

我花了一些时间查找这个并阅读文档以弄清楚如何 删除重复项。首先我认为类型类会很棒但是那些 对于 F# 来说显然是一个陌生的概念。然后我想也许是一个接口 可能会很好,但似乎我需要为那些使用的人提供完整的课程 实际的方法使我现在拥有的类型层次结构变得非常复杂。 尝试将类型保留并解决该问题没有成功,没有 期待它,但我还是尝试了。

types f# docx code-duplication
1个回答
0
投票

这里的问题是

WordTableCell
WordDocument
提供类似的 API,但不共享基类或接口。我认为处理这个问题的最简单方法是通过为每个类创建自己的
addParagraph
addTable
函数来消除差异,然后围绕这两个辅助函数统一逻辑:

    let rec addPartUnified (part: DocumentPart) addParagraph addTable =
        match part with
        | Par paragraph ->
            for run in paragraph do
                let wordParagraph : OfficeIMO.Word.WordParagraph = addParagraph run.text
                ()
        | Img image ->
            (addParagraph "").AddImage (image.path, 100, 100, OfficeIMO.Word.WrapTextImage.Square) |> ignore
        | Tab table ->
            let wordTable : OfficeIMO.Word.WordTable = addTable (table.rows, table.cols)
            for cell in table.cells do
                for row = cell.height - 1 downto 0 do
                    for col = cell.width - 1 downto 0 do
                        wordTable.Rows[row+cell.y].Cells[col+cell.x].MergeHorizontally 1
                        wordTable.Rows[row+cell.y].Cells[col+cell.x].MergeVertically 1
                FillWordContainer (Cell wordTable.Rows[cell.y].Cells[cell.x]) cell.content
        | Lst listing ->
            let wordListing = (addParagraph "").AddList OfficeIMO.Word.WordListStyle.Bulleted
            for text in listing do
                wordListing.AddItem text |> ignore

然后您可以像这样调用统一函数:

    and addPart (part: DocumentPart) (master: WordContainer) =
        match master with
        | Cell cell ->
            addPartUnifiied part cell.AddParagraph cell.AddTable
        | Doc document ->
            addPartUnifiied part document.AddParagraph document.AddTable
© www.soinside.com 2019 - 2024. All rights reserved.