2016-05-06 47 views
0

我是功能性編程的新手,需要製作一個簡單的紙牌遊戲,但在錄製功能時遇到問題。卡牌遊戲的OCaml rec函數

假設我有一個5名球員的名單。現在我用玩家當前的牌爲每個玩家打印一個菜單,然後玩家放下一張牌並繪製一張新牌。

我需要跑直到甲板沒有牌。

這是我的代碼:

let rec round deck players = 
    match deck with 
    | [] ->() 
    | h::t -> (match players with 
        | x::xs -> print_mazo deck; 
        print_play x; 
        let i = read_int() in 
        let (newhand, carta) = drop x.mano i in 
        let (newdeck, newhand2) = draw deck newhand 1 in 
        print_ronda x carta; 
        round newdeck xs 
        | [] -> round newdeck players 
      ) 

我得到這個錯誤:

Error: Unbound value newdeck 
+0

看起來問題與'read_int'一致:它應該是'read_int()' –

+1

(1)最好有一個實際編譯的最小化完整示例。 (2)至少你應該在錯誤發生的地方標記出來。 –

+3

你不能改變你的問題。它使舊的答案無意義。 –

回答

0

其實,你的代碼很奇怪。讓我來向您解釋:

let rec round deck players = 
match deck with 
    | [] ->() 
    | h::t -> (match players with 
       | x::xs -> (* Some code *) 
       let (newdeck, newhand2) = draw deck newhand 1 in 
       round newdeck xs (* good recursive call *) 
       | [] -> round newdeck players (* bad recursive call *) 
     ) 

爲什麼這是bad recursive call?因爲您在模式匹配的第一個分支中聲明瞭newdeck,但在第二個分支中沒有聲明。所以,當你寫| [] -> round newdeck playersnewdeck從哪裏來?

這就像寫

let f x = let a = 3 in x + a 
let y = a 

你的事實,這是a本地f同意嗎?如果您同意,這與您的newdeck位於模式匹配的第一個分支位置相同。

+0

噢,我看到了,我需要一種方法來在最終模板中使用我修改後的套牌。 –

+0

實際上,如果您仔細查看代碼,如果玩家列表爲空,則您的'newdeck'等於參數'因爲對'round'的遞歸調用總是在'newdeck'上完成。 – Lhooq

1

我覺得你眼前的問題是,你必須:

let i = read_int 

但你需要

let i = read_int() 

read_int本身就是一個函數,它在OCaml(以及任何FP語言)中是相當普通的值。所以將i綁定到這個值並不是一個錯誤。但是,編譯器注意到該值沒有正確的類型,即int。你想實際上的調用的功能;即,您需要將其應用於輸入值。在read_int的情況下,它始終採用相同的輸入值()

瀏覽其餘的代碼,我沒有看到任何使用值t。我懷疑還有更多的工作要做,通過球員名單。