Math 定义递归数据结构

Math 定义递归数据结构,math,haskell,Math,Haskell,我试图学习Haskell,认为它将是实现的完美语言。在某种程度上,我在Python中这样做是为了自学OOP原理和运算符重载,但Haskell吸引了我,因为它的语法似乎更数学化,我非常喜欢它的数学背景。而且,懒散地实现无限列表是非常令人惊讶的 无论如何,到目前为止,我拥有的是一个可编译的数据结构,但我使用它编写的第一个函数给出了: Prelude> :l cgt [1 of 1] Compiling Main ( cgt.hs, interpreted ) cgt.

我试图学习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)
我意识到游戏有点像上面讨论的树,但是它们有额外的限制

  • 一个位置(树节点的近亲)可以有许多可能的移动
  • 一个位置只能包含其他游戏
  • 有一个特殊的游戏,零,没有可能的动作
  • 所有的游戏都是用零创建的
  • 因此,当我写
    putL
    时,我说,“把一个游戏
    a
    和另一个游戏
    b
    ,把
    a
    放在
    b
    的第一部分,把
    b
    的第二部分放在一边,返回一个位置(这是一种游戏)。”至少,这是我试图做的。相反,Haskell认为我返回的类型是
    ([Game],b0)
    ,我不知道为什么


    谢谢大家!!感谢您的帮助。

    您不能在
    游戏类型的东西上使用
    fst
    snd
    功能。由于您尚未在数据构造函数
    Zero
    Position
    中声明字段名称,因此实际访问它们的唯一方法是通过模式匹配。(注意,我还删除了
    位置
    构造函数中不必要的元组)


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

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

    • a:fst b
      必须具有类型
      [游戏]
      ——同意,是吗
    • 因此
      a
      必须具有类型
      Game
      。。。(的确如此,万岁)
    • …和
      fst b
      必须具有类型
      [游戏]
    • 将一对作为输入,并生成该对的第一个元素,因此
    • b
      必须具有类型
      ([Game],b0)
      (对于我们尚未计算出的某些类型
      b0
      )(这是预期的类型)
    • 这是一个问题,因为根据
      putL
      的类型签名,
      b
      必须具有类型
      Game
      (这是实际类型)-它不能是一对

    实际上,零游戏已经由
    位置[][]
    表示,因此不需要额外的构造函数。我明白了。我使用元组是因为我只想有两组位置,但这是不必要的,因为这两个列表是在数据结构中定义的。对于函数,你可以定义什么类型作为一个位置,返回我想要的。
    data Game
      = Zero
      | Position [Game] [Game]
    
    putL :: Game -> Game -> Game
    putL game Zero = ???
    putL game (Position games1 games2) = Position (game : games1) games2