定义递归数据结构

rev*_*v_s 5 math haskell

我正在努力学习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.
Run Code Online (Sandbox Code Playgroud)

这是我的代码......

--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)
Run Code Online (Sandbox Code Playgroud)

我意识到游戏有点像在Wikibook上讨论过的树,但它们还有其他限制.

  1. 位置(树节点的亲属)可以有许多可能的移动
  2. 职位可能只包含其他游戏
  3. 有一个特殊的游戏,零,没有可能的动作.
  4. 所有游戏都是使用Zero构建的.

因此,当我写作时,putL我说:"拿一个游戏a和另一个游戏b,并将其a纳入第一部分b,然后b单独留下第二部分,返回一个位置(这是一种游戏)." 至少,这就是我想要做的.相反,Haskell正在考虑我正在返回的类型([Game], b0),我不知道为什么.

谢谢!我感谢您的帮助.

dfl*_*str 10

你不能在类型的东西上使用fstsnd函数Game.因为你没有在你的数据的构造函数声明为您的域的名称ZeroPosition,实际访问它们的唯一方法就是通过模式匹配.(注意我也删除了Position构造函数中不必要的元组)

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

putL :: Game -> Game -> Game
putL game Zero = ???
putL game (Position games1 games2) = Position (game : games1) games2
Run Code Online (Sandbox Code Playgroud)

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

  • 实际上,零游戏已经由`Position [] []`表示,因此不需要额外的构造函数. (4认同)

dav*_*420 6

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

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