Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining recursive data structures

Tags:

math

haskell

I'm trying to learn Haskell, thinking that it would be the perfect language to implement Combinatorial Game Theory. I've done this to some extent in Python to teach myself OOP principles and operator overloading, but Haskell attracts me because it seems more mathematical in its syntax, and having a math background I really like that. Also, having lazily implemented infinite lists is pretty amazing.

Anyway, what I have so far is a data structure that compiles but the first function I've written using it gives me:

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.

Here is my code...

--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)

I realize that a Game is somewhat like a Tree as discussed on the Wikibook , but they have additional restrictions.

  1. A Position (kin to a tree node) can have many possible moves
  2. A Position may only contain other Games
  3. There is a special Game, Zero, that has no possible moves.
  4. All games are built up using Zero.

So when I wrote putL I say, "Take a Game a and another Game b, and cons a into the first part of b, and leave the second part of b alone, returning a Position (which is a kind of Game)." At least, that is what I am trying to do. Instead Haskell is thinking the type I'm returning is ([Game], b0) and I don't know why.

Thank you! I appreciate your help.

like image 684
rev_s Avatar asked Oct 02 '12 12:10

rev_s


People also ask

What defines recursion?

Definition of recursion 1 : return sense 1. 2 : the determination of a succession of elements (such as numbers or functions) by operation on one or more preceding elements according to a rule or formula involving a finite number of steps.

Is recursive function a data structure?

A recursive data structure can be defined as a data structure that can be broken down into simple or miniature instances of itself. For example, trees are composed of small trees and leaf nodes while lists can contain smaller lists as their elements.

What is recursion and its types in data structure?

Recursion are mainly of two types depending on whether a function calls itself from within itself or more than one function call one another mutually. The first one is called direct recursion and another one is called indirect recursion.

What is recursive function example?

Simple examples of a recursive function include the factorial, where an integer is multiplied by itself while being incrementally lowered. Many other self-referencing functions in a loop could be called recursive functions, for example, where n = n + 1 given an operating range.


2 Answers

dflemstr's answer is correct. I am going to explain the error message you got.

  • a : fst b must have type [Game] --- agreed, yes?
  • therefore a must have type Game... (and it does, hooray)
  • ...and fst b must have type [Game]
  • fst takes a pair as input, and yields the first element of the pair, so...
  • ...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
like image 32
dave4420 Avatar answered Sep 23 '22 19:09

dave4420


You can't use the fst and snd functions on something of type Game. Since you haven't declared names for your fields in your data constructors Zero and Position, the only way to actually access them is via pattern matching. (Note that I also removed the unnecessary tuple in the Position constructor)

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

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

Now, I obviously don't know what you want to happen for the Zero constructor, so you'll have to fill in those ???'s yourself.

like image 198
dflemstr Avatar answered Sep 24 '22 19:09

dflemstr