定义递归数据结构

时间:2012-10-02 12:43:40

标签: math haskell

我试图学习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. 所有游戏都是使用Zero构建的。
  5. 所以当我写putL时,我说,"将游戏a和另一个游戏b以及a合并到b的第一部分1}},单独留下b的第二部分,返回一个位置(这是一种游戏)。"至少,这就是我想要做的。相反,Haskell认为我返回的类型是([Game], b0)而我不知道为什么。

    谢谢!感谢您的帮助。

2 个答案:

答案 0 :(得分:10)

您无法在fst类型的某些内容上使用sndGame函数。由于您尚未在数据构造函数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构造函数做些什么,所以你必须自己填写???

答案 1 :(得分:6)

dflemstr的回答是正确的。我将解释你得到的错误信息。

  • a : fst b必须有[Game]类型---同意,是吗?
  • 因此a必须有Game类型...(而且确实如此,很好)
  • ... fst b必须包含[Game]
  • 类型
  • fst将一对作为输入,并产生该对的第一个元素,因此......
  • ... b必须有([Game], b0)类型(对于我们尚未制定的某种类型b0)(这是预期的类型)
  • 这是一个问题,因为根据putL的类型签名,b必须有Game类型(这是实际类型)---它不能是一对