2017-04-20 49 views
3

我在Ruby中有以下代碼,它需要一個'melds'列表並創建一個樹結構,以便找到最佳組合並返回它。我想將此代碼轉換爲F#等價物,但我很難想出一種方法來實現它,因爲F#沒有簡單的方法來創建節點樹(至少我知道)。需要幫助將Ruby代碼轉換爲F#

我一直沒有使用F#很長時間,所以我沒有很好的理解它或使用高階函數的很多知識,所以如果任何人都知道如何轉換此代碼,它會很大不勝感激!謝謝。

class MeldNode 
    attr_accessor :cards, :deadwood, :parent 
    def initialize(cards, parent) 
    @parent = parent 
    @cards = cards 
    @deadwood = count_deadwood(cards) 
    if (parent != nil) 
     @deadwood = @parent.deadwood + @deadwood 
    end 
    end 
end 

def build_meld_tree(melds, root_meld) 
    best = root_meld 
    melds.each do |m| 
    n = MeldNode.new(m, root_meld) 
    new_tree = build_meld_tree(clean_meld_group(melds, m), n) 
    best = new_tree if (best == nil) || (new_tree.deadwood > best.deadwood) 
    end 
    best 
end 
+3

你有什麼試過? F#有遞歸,所以我沒有看到代碼中的任何東西都不會'簡單'。 – ildjarn

+3

我不明白你的意思是「F#沒有簡單的方法來創建節點樹」。 F♯是一種全功能的命令式不純OO語言(即使這不是使用它的首選方式),所以您可以在Ruby中做同樣的事情。此外,F♯具有代數和類型(在F♯中稱爲*判別聯合*),它們對於表示樹是完美的,事實上,這可能是激勵代數數據類型的最廣泛的例子之一:類型樹<'a> ='a |的葉子樹的節點<'a> *樹<'a>'。 [注意:我實際上不知道F♯,可能有語法錯誤。] –

+1

我對F#一無所知,但有幾個快速Google提示存在Ruby - > C#和C# - > F#轉換器,所以也許你可以分兩步做。 –

回答

1

因此,採取完全相同的代碼,並將其移植到F#:

type MeldNode<'a> = 
    { cards : 'a; deadwood : int; parent : MeldNode<'a> option } 

    static member New cards (parent:MeldNode<'a> option) = 
    { 
     cards = cards; 
     deadwood = (Array.length cards) + (if parent.IsSome then parent.Value.deadwood else 0); 
     parent = parent 
    } 


let rec buildMeldsTree rootMeld (melds:'a[] list) = 
    if List.isEmpty melds then None // ensure terminating case 
    else 
    melds 
    |> List.map (fun m -> 
     let n = MeldNode<'a>.New m rootMeld 
     buildMeldsTree (Some n) (cleanMeldGroup melds m) 
    ) 
    |> List.append (if rootMeld.IsNone then [] else [ rootMeld.Value ]) 
    |> List.maxBy (fun (n:MeldNode<'a>) -> n.deadwood) 
    |> Some 

我看到你更新的一個變種稱爲best。 F#更喜歡不可變的變量,所以使用這種獲得「最佳」組合的方式符合該偏好。希望這可以幫助!