How can I improve my Haskell code and make it work?

199 views Asked by At

In my code I call the validateFEN function with a FEN String. A Fen string looks like this for example:

",w84,w41,w56,w170,w56,w41,w84,/,,w24,w40,w17,w40,w48,,/,,,w16,w16,w16,,,/,,,,,,,,/,,,,,,,,/,,,,,,,,/,,,b1,b1,b1,,,/,,b3,b130,b17,b130,b129,,/,b69,b146,b131,b170,b131,b146,b69,"

The function should take the string and check if it's a FEN string. How does it know if it's a FEN string? -> My string has 9 rows and 9 columns. I don't need to check if the pieces (example: w86) are at their right position.

validateFEN' b = help3 (filter (\x -> x == ',' || x == '/' ) b)

help3 b =  (if help1 b == True then (if head (drop 8 b) == '/' then help3 (drop 9 b) else False) else False )

help1 b = help2 (take 8 b)

help2 b = foldr (+) 0 (map (\x -> if x == ',' then 1 else 0 )b) == 8

Why do I keep getting the error for a empty list?

Exception: Prelude.head: empty list

I understand that with my code there is no stop. The program doesn't know when the string is "correct".

Is there a shorter simpler way of doing this?

1

There are 1 answers

1
Daniel Wagner On BEST ANSWER

One way to reuse existing library functions to make this clearer would be to use stripPrefix.

help3 s = case stripPrefix ",,,,,,,,/" s of
    Nothing -> False
    Just s' -> help3 s'

Of course, you still need to handle the final case, where there is no terminating /. This can be done with a single extra clause:

help3 ",,,,,,,," = True
help3 s = {- ... -}

You might want to ponder whether validateFEN' should have a similar special case for the empty string.

BUT I would strongly suggest simply not implementing validateFEN' in the first place. My guess is that the plan is something like this:

  1. Check if a string is valid FEN.
  2. Process the string, assuming FEN-ness.

Instead, I recommend the following approach:

  1. Parse the string into a native data structure that represents the information available in a FEN string.
  2. Process the native structure.

Step 1, if written with standard parsing solutions, will "accidentally" validate the string -- i.e. running your parser will return something like Either Error FEN, which you can pattern match on to either discover that the string is invalid or that it is valid and has been turned into a more idiomatic representation.