Parse error in a case statement
Asked Answered
G

2

9

I am trying to convert a Maybe Int to an Int in Haskell like this:

convert :: Maybe Int -> Int
convert mx = case mx of 
               Just x -> x
              Nothing -> error "error message"

When I compile it, Haskell tells me: parse error on input 'Nothing'.

I need this, because I want to get the Index of an element in a list with the elem.Index function from the Data.List module and then use this index on the take function. My problem is that elemIndex returns a Maybe Int, but take needs an Int.

Genetics answered 27/6, 2015 at 11:7 Comment(2)
I hope you understand that “converting” this way is not really a clever idea: you're essentially subverting the type system. Only do this when you're absolutely sure that the argument is a Just, but the type checker can't proove it. And even then it's better to explicitly match case mx of {Just x -> x} right where you need it, not through a helper function. The reason being: if this match does fail, it will give you a nice clear error message telling where it happened. Your convert will always give you the same error message when the assumption fails, no matter where you use it.Volcanism
It sounds like you just need takeWhile (/= item)?Karlee
V
12

This is a whitespace problem. The case clauses need to be indented to the same level.

convert :: Maybe Int -> Int
convert mx = case mx of 
               Just x -> x
               Nothing -> error "error message"

Remember to use only spaces, no tabs.

Volcanism answered 27/6, 2015 at 11:9 Comment(2)
That said, what the OP seems to want, is fromJust.Puto
@bereal: mhhhh... I wouldn't recommend fromJust. See my comment above to the question. (It's still better than convert, though.)Volcanism
B
2

To add to @leftaroundabout's answer, I think I might provide you with some other options.

First off, you shouldn't make unsafe things like this: your program will fail. It's much cleaner to keep it as a Maybe Int and operate as such, safely. In other words, this was a simple parse error, but making incomplete functions like this may cause far greater problems in the future.

The problem you've encountered it, how can I do that?

We might make a better function, like this:

mapMaybe :: (a -> b) -> Maybe a -> Maybe b
mapMaybe f m = case m of
     Just a  -> f a
     Nothing -> Nothing

Which would allow you to write:

λ> (+ 15) `mapMaybe` Just 9
Just 24

However, there is a function called fmap, which 'maps' a function over certain data-structures, Maybe included:

λ> (== 32) `fmap` Just 9
Just False

and if you have imported Control.Applicative, there is a nice operator synonym for it:

λ> show <$> Just 9
Just "9"

If you want to know more about these data-structures, called Functors, I would recommend reading Learn-you a Haskell.

Bouillabaisse answered 27/6, 2015 at 11:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.