5

我正在尝试学习 Haskell,认为这将是实现组合博弈论的完美语言。我在某种程度上用 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,我说,“拿一个 Gamea和另一个 Game b,然后将 consa放入 的第一部分b,而将第二部分b单独留下,返回一个 Position (这是一种 Game)。” 至少,这就是我想要做的。相反,Haskell 认为我返回的类型是([Game], b0),我不知道为什么。

谢谢!我感谢您的帮助。

4

2 回答 2

10

你不能在 type 的东西上使用fstandsnd函数Game。由于您没有在数据构造函数中为字段声明名称,Zero并且Position,实际访问它们的唯一方法是通过模式匹配。(请注意,我还删除了Position构造函数中不必要的元组)

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

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

现在,我显然不知道你想为Zero构造函数发生什么,所以你必须自己填写那些???

于 2012-10-02T12:49:49.133 回答
6

dflemstr 的回答是正确的。我将解释您收到的错误消息。

  • a : fst b必须有类型[Game]——同意,是吗?
  • 因此a必须具有类型Game...(确实如此,万岁)
  • ...并且fst b必须有类型[Game]
  • fst将一对作为输入,并产生对的第一个元素,所以......
  • ...b must have type ([Game], b0) (for some type b0 that we haven't worked out yet) (this is the expected type)
  • this is a problem because according to the type signature for putL, b must have type Game (this is the actual type) --- it can't be a pair
于 2012-10-02T13:24:58.903 回答