Guilherme Moreira
Guilherme Moreira

Reputation: 121

If error, assign a specific value to variable

so I have this code fragment: where exponent = read (tail (dropWhile (/= '^') (head xs))) :: Int but there is a possibility of the list inside tail being empty, so that would mean there would be an error looking for a tail inside an empty list. Is there a way to do something like: if error: exponent = 1 ?

Here is the full function if it helps in any way :)

internalRepresentation :: [String] -> [(Int,Char ,Int)]
internalRepresentation xs
    |null xs = []
    |all isDigit (head xs) = (read (head xs), ' ', 0) : internalRepresentation (tail xs)
    |head (head xs) == '-' = (-read (takeWhile isDigit (pos_mon)) :: Int, head (dropWhile isDigit (pos_mon)), exponent) : internalRepresentation (drop 1 xs)
    |otherwise = (read (takeWhile isDigit (head xs)) :: Int, head (dropWhile isDigit (head xs)), exponent) : internalRepresentation (drop 1 xs)
    where pos_mon = tail (head xs)
          exponent = read (tail (dropWhile (/= '^') (head xs))) :: Int

Thanks for your time!

Upvotes: 1

Views: 140

Answers (1)

Noughtmare
Noughtmare

Reputation: 10695

The functions read, head, and tail are partial which means that they can fail with an error as you have experienced. That is why many people avoid those functions. Personally, I would write it like this:

import Text.Read (readMaybe)

internalRepresentation' :: String -> (Int, Char, Int)
internalRepresentation' xs =
  case reads xs of
    [(n, "")] -> (n, ' ', 0)
    [(n, x:xs')] ->
      case readMaybe (drop 1 (dropWhile (/= '^') (x:xs'))) of
        Just e -> (n, x, e)
        Nothing -> error "Malformed exponent"
    _ -> error "Malformed internal representation"

internalRepresentation :: [String] -> [(Int, Char, Int)]
internalRepresentation xs = map internalRepresentation' xs

You can probably avoid that ugly drop 1 (dropWhile (/= '^') (x:xs')) too if you constrain your input a bit more. But I'm not completely sure what this function is actually supposed to do, so I can't help much more.

For example, if you only want to parse strings that look exactly like 123^456 (without other characters in between), then you can write it like this:

internalRepresentation' xs =
  case reads xs of
    [(n, "")] -> (n, ' ', 0)
    [(n, '^':xs')] ->
      case readMaybe xs' of
        Just e -> (n, '^', e)
        Nothing -> error "Malformed exponent"
    _ -> error "Malformed internal representation"

Upvotes: 2

Related Questions