Samara92
Samara92

Reputation: 85

How can get a position in a List in Haskell using Maybe

I have to write a function in Haskell for:

safeIndex :: [b] -> Integer -> Maybe b

so when it get an Element from a List it will give us a Just when it does not it gives us Nothing

ghci> [1..10] 'safeIndex' 3

Just 4

ghci> [1..10] 'safeIndex' 10

Nothing

and I really not succeeding in that

Upvotes: 0

Views: 411

Answers (3)

J. Abrahamson
J. Abrahamson

Reputation: 74384

It's a small change from the unsafe version.

(!!) :: [a] -> Int -> a
[]     !! n = error "What"
(a:as) !! 0 = a
(a:as) !! n = as !! (n-1)

Instead of failing with error we should fail with Nothing. This will cause the rest of the function to fail to typecheck as our return type has changed

(!!) :: [a] -> Int -> Just a

To fix this, we must tag successes with Just as well. Finally, the recursive call should be thought carefully about. Does it require a tag of any kind? It depends on whether or not it fails, but we can't know that until we actually step into the recursive call...

Upvotes: 1

bheklilr
bheklilr

Reputation: 54078

According to hoogle, it doesn't look like one exists in the base libraries, but you could write one pretty easily, although I would name it !?:

(!?) :: [a] -> Int -> Maybe a
[]     !? _ = Nothing
(x:xs) !? 0 = Just x
(x:xs) !? i = ???

I'll leave you to fill in the ??? case, you can get some hints from @Sibi's answer to do so. Keep in mind that this doesn't handle negative indices, if you want that as well then I'd suggest using guards instead:

[] !? _ = Nothing
(x:xs) !? i
    | i < 0  = ???
    | i == 0 = Just x
    | otherwise = ???

Upvotes: 0

Sibi
Sibi

Reputation: 48766

I will give you hints on how to achieve that:

  • Think of the case on what to do when the input list is empty.
  • Think of the alternative case on what to do when the input list is non-empty.

You have to solve it using recursion. When you have an empty list, you have to return Nothing. In case you find an element for a particular index you can wrap the result in Just and return it. I think it should be now straight forward enough to translate this into Haskell code.

Upvotes: 1

Related Questions