ProgrammerPotato
ProgrammerPotato

Reputation: 515

How to read recursive data structures from String in Haskell?

For example;

  data TRAINING=AGAIN Int [TRAINING]
                |RUN
                |JUMP
                |PUNCH Int 
           deriving (Eq,Show,Read)

is defined and I want that if the User enters something like:

  "RUN, PUNCH 15, AGAIN 3 [JUMP, AGAIN 2 [PUNCH 20]]"

then the program should return

  [RUN,PUNCH 15,AGAIN 3 [JUMP,AGAIN 2 [PUNCH 20]]]

So I wrote

  fight :: String->[TRAINING]
  fight xs=[read xs ::TRAINING]

but I am getting "no parse Exception". I am novice and I want to know what a "no parse Exception" is and how I can fix it ?

Upvotes: 1

Views: 283

Answers (2)

גלעד ברקן
גלעד ברקן

Reputation: 23955

In other words, following jozefg's answer:

fight xs = read xs ::[TRAINING]

and also:

"[RUN, PUNCH 15, AGAIN 3 [JUMP, AGAIN 2 [PUNCH 20]]]"

Upvotes: 1

daniel gratzer
daniel gratzer

Reputation: 53911

A no parse exception means that what you gave Haskell isn't the correct pattern for the instance of Read. In this case it's because list's are shown like this:

[<show element>,<show element>...]

And you're missing the outer brackets. Fixing it is as easy as seeing what the output should be:

Prelude> show [RUN,PUNCH 15,AGAIN 3 [JUMP,AGAIN 2 [PUNCH 20]]]
         "[RUN,PUNCH 15,AGAIN 3 [JUMP,AGAIN 2 [PUNCH 20]]]"

So you need to surround the whole thing with []'s. Your function is right, you just have a slightly incorrect input string.

If you don't like this restriction, it may be time to just write a simple parser with Parsec or similar. Though this might be a bit challenging if you're totally new to Haskell.

Upvotes: 6

Related Questions