0

I would need to get the position of an element in may array of type Array Int Int. I found the method elemIndex or find to get the position. My problem is, that I don't need the prefix Just 5 for example. So how I only get the number 5 in my example?

1
  • 3
    What do you want to return if the element is not in the list? Commented Nov 3, 2013 at 14:04

2 Answers 2

7

The principle

To safely extract a value from a Maybe a value, you can either use pattern matching, like so:

case elemIndex 'C' list of
  Just n -> "You can find C at position " ++ show n
  Nothing -> "There is no C in the list."

This will return something like

"You can find C at position 2"

or

"There is no C in the list."

depending on whether or not there is a C in the list.

Making it convenient

Of course, this kind of pattern matching is unwieldy to write all the time, so there exists a function called maybe that does pretty much the same thing. If you look at its type signature, you see that

maybe :: b -> (a -> b) -> Maybe a -> b

So it takes a "default value" of type b, and a function from a to b, and will return a b. Whether or not this is the default value depends on whether or not the Maybe a value exists or is Nothing. For example, if you want to check if a list element is allowed entry into an 18+ club, you can do

maybe False (\n -> n >= 18) (elemIndex 'C' list)

This will say False if the index is less than 18 or if the element doesn't exist in the list. If it does exist, it will check if it's greater or equal to 18, and then return True.

Keeping the Just

What I've told you so far is how to get rid of the Just in a safe way. Sometimes, you can't get rid of the Just just yet – sometimes you have no sensible value to return if you have a Nothing on your hands instead of the Just. What you can do then is manipulate values when they are still inside the Just. For example, to subtract 15 from a value inside a just, you just do

fmap (subtract 15) (Just 23)

which will return

Just 8

So you see how fmap sort of takes a Just something value and applies the function to the something part of it, keeping the Just outside. If you would do

fmap (subtract 15) Nothing

it would just keep the Nothing, so the result would be

Nothing

Making it unsafe (kids, don't try this at home!)

Maybe is great because it is an error handling system that forces you to Do Things Right. You just can't ignore the possibility of an error (represented by Nothing.) Another common error handling system is terrible with this. That system is the system of exceptions. Nobody will know if you blatantly ignore that an exception can occur, which is a basis for very unsafe programs.

So you really want to keep the Just until you can toss it away and at the same time replace a potential Nothing value with something sensible.

If you can guarantee that there is no possibility of a Nothing value. If you know for sure that everytime you call elemIndex the element is going to be somewhere in the list, then it's okay to use fromJust. fromJust will blindly try to take a value out of a Just, without giving a dang about what happens if there is no Just there. fromJust will simply explode your program (throw an exception) if something went wrong.

As you understand, you have to use it with much care.

Being unsafe with style

However, as Jedai points out in a comment, even if you shouldn't be able to get a Nothing value, it is better to be explicit about it. Instead of using fromJust, consider doing something like

fromMaybe (error "The input " ++ show list ++ " shouldn't create a Nothing value!")
  (elemIndex 'C' list)

which will blow up with a very specific error message, pinpointing where something must have gone wrong.

This is of course the same thing as the pattern match that looks like

case elemIndex 'C' list of
  Just n -> n
  Nothing -> error "The input " ++ show list ++ " shouldn't create a Nothing value!"

only compacted into the standard fromMaybe function.

Sign up to request clarification or add additional context in comments.

Comments

3

Use fromJust from Data.Maybe. Like:

fromJust $ elemIndex 2 [1,2,3,4,5]

And you will get only 1.

But, this will fail if you don't have desired element in the list and you'll get an exception:

*** Exception: Maybe.fromJust: Nothing

3 Comments

Use fromJust only if you can show that the element you are looking for exists in the list. In any other case, Haskell has fantastic facilities for manipulating things inside a Maybe value – so you can keep the Just around until you are sure you can safely drop it and still return a sensible value.
that will work great for me. the element I am searching for is definitely in the list so I wont get an error message. thank you very much
Even in this case you should probably use fromMaybe that allows you to specify a default case (for Nothing) and put a precise error in there that'll allows you to pinpoint the source of the problem if you were wrong because the default error message won't be much help... So something like fromMaybe (error "Impossible ! The element should be in the list in this function _fun_") $ elemIndex...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.