2012-10-02 83 views
5

我在努力學習Haskell,認爲這將是實現Combinatorial Game Theory的完美語言。我在Python中做了一些這樣的工作來教自己的OOP原則和運算符重載,但Haskell吸引我,因爲它的語法看起來更加數學化,並且有一個我非常喜歡的數學背景。而且,懶惰地實施無限列表是相當了不起的。定義遞歸數據結構

不管怎麼說,我迄今爲止的是,編譯,但我已經用它寫的第一功能的數據結構給我:

Prelude> :l cgt 
[1 of 1] Compiling Main    (cgt.hs, interpreted) 

cgt.hs:8:30: 
    Couldn't match expected type `([Game], b0)' with actual type `Game' 
    In the first argument of `fst', namely `b' 
    In the second argument of `(:)', namely `(fst b)' 
    In the expression: a : (fst b) 
    Failed, modules loaded: none. 

這裏是我的代碼...

--A game that is Zero (base case) is two empties 
--Anything else must be two lists of games, a left list and a right list. 

data Game = Zero 
      | Position ([Game], [Game]) 

putL :: Game -> Game -> Game 
putL a b = Position (a :(fst b), snd b) 

我意識到遊戲有點像Wikibook上討論的樹,但它們有其他限制。

  1. 的位置(親屬到樹節點)可以有很多可能的行動
  2. 的位置可能只包含其他遊戲
  3. 有一個特殊的遊戲,零,即沒有可能的行動。
  4. 所有遊戲都是使用零建立的。

所以,當我寫putL我說,「把一個遊戲a和另一場比賽b,利弊ab的第一部分,並獨自離開的b第二部分,返回的位置(這是一個一種遊戲)「。至少,這正是我想要做的。相反,Haskell認爲我返回的類型是([Game], b0),我不知道爲什麼。

謝謝!我感謝您的幫助。

回答

10

您不能在Game類型的東西上使用fstsnd函數。由於您尚未在數據構造函數ZeroPosition中爲您的字段聲明名稱,實際訪問它們的唯一方法是通過模式匹配。 (請注意,我也去掉了不必要的元組在Position構造函數)

data Game 
    = Zero 
    | Position [Game] [Game] 

putL :: Game -> Game -> Game 
putL game Zero = ??? 
putL game (Position games1 games2) = Position (game : games1) games2 

現在,我顯然不知道要發生的Zero構造什麼,所以你必須填寫這些???「你自己。

+4

實際上,零和遊戲已經被'位置[] []'表示,所以沒有必要爲這額外的構造函數。 – hammar

+0

我明白了。我使用了一個元組,因爲我只想要兩組位置,但這是不必要的,因爲這兩個列表是在數據結構中定義的。 而對於函數,您可以定義什麼類型作爲位置進入,返回我想要的。 –

6

dflemstr的回答是正確的。我要解釋你得到的錯誤信息。

  • a : fst b必須有型號[Game] ---同意,是嗎?
  • 因此a必須有類型Game ...(和它,萬歲)
  • ...和fst b必須有類型[Game]
  • fst在一對作爲輸入,併產生所述一對的第一個元素,所以...
  • ...b必須有類型([Game], b0)(對於某些類型b0,我們還沒有制定出來呢)(這是預期型)
  • 這是一個問題,因爲根據對putL類型簽名,b類型必須Game(這是實際型)---它不能是一對
+0

謝謝,這是更清晰! –