我试图学习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中讨论的树,但它们还有其他限制。
所以当我写putL
时,我说,"将游戏a
和另一个游戏b
以及a
合并到b
的第一部分1}},单独留下b
的第二部分,返回一个位置(这是一种游戏)。"至少,这就是我想要做的。相反,Haskell认为我返回的类型是([Game], b0)
而我不知道为什么。
谢谢!感谢您的帮助。
答案 0 :(得分:10)
您无法在fst
类型的某些内容上使用snd
和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
构造函数做些什么,所以你必须自己填写???
。
答案 1 :(得分:6)
dflemstr的回答是正确的。我将解释你得到的错误信息。
a : fst b
必须有[Game]
类型---同意,是吗?a
必须有Game
类型...(而且确实如此,很好)fst b
必须包含[Game]
fst
将一对作为输入,并产生该对的第一个元素,因此...... b
必须有([Game], b0)
类型(对于我们尚未制定的某种类型b0
)(这是预期的类型)putL
的类型签名,b
必须有Game
类型(这是实际类型)---它不能是一对