Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell Maybe type -> type

I am running into this problem :

Couldn't match expected type ‘Int’ with actual type ‘Maybe Int’

Can I somehow convert ‘Maybe Int’ into ‘Int’??

if index == Nothing 
   then 
     do 
       let index = 0
       putStrLn(fancyPrint2 $ kaasasOlevList !! index)
   else 
     do 
       let index = index
       putStrLn(fancyPrint2 $ kaasasOlevList !! index)

I tried like this, but this gives me :

Exception: <<loop>>
like image 665
Fiedberg Nichenko Avatar asked Jul 19 '26 10:07

Fiedberg Nichenko


2 Answers

You have several different options to get around this

First is using your if statement, but with a small modification (Avoid doing this though)

if index == Nothing 
   then 
     do 
       let index' = 0
       putStrLn $ fancyPrint2 $ kaasasOlevList !! index'
   else 
     do 
       let (Just index') = index
       putStrLn $ fancyPrint2 $ kaasasOlevList !! index'

I'm writing index' here, because Haskell doesn't allow you to overwrite existing variables, it does however let you hide them. But generally it's better practice to label "modified" versions of a variable with a "prime" symbol (') at the end. That way you can always access the original if need be.

Second you can use a case expression which turns your code into

case index of
  Just i  -> putStrLn $ fancyPrint2 $ kaasasOlevList !! i
  Nothing -> putStrLn $ fancyPrint2 $ kaasasOlevList !! 0

Or if you clean it up a bit using a where clause:

case index of
  Just i  -> putIndex i
  Nothing -> putIndex 0
where putIndex x = putStrLn $ fancyPrint2 $ kaasasOlevList !! x

Lastly there's fromMaybe which lets you do this:

import Data.Maybe (fromMaybe)

-- ...

do
  let index' = fromMaybe 0 index
  putStrLn $ fancyPrint2 $ kaasasOlevList !! index'

You can also use guards. But seeing as I don't know where your code-snippet comes from, I don't know if it's reasonable to use guards.

You can read more about guards, case expressions and pattern matching here

like image 55
Electric Coffee Avatar answered Jul 21 '26 20:07

Electric Coffee


Yes, you can use the fromMaybe function:

fromMaybe :: a -> Maybe a -> a

It works as follows, the first argument is the default value, something you use in case the second is Nothing, next follows the Maybe a, if that value is Just x, x is returned. So an implementation of fromMaybe could be:

fromMaybe _ (Just x) = x
fromMaybe d Nothing = d

So you could use:

import Data.Maybe(fromMaybe)

--...

putStrLn(fancyPrint2 $ kaasasOlevList !! (fromMaybe 0 index))

Without all the if-then-else wich is rather un-Haskell.


Why does it loop? Well in case that your index is of the form Just x, it goes into the following branch:

do 
   let index = index
   putStrLn(fancyPrint2 $ kaasasOlevList !! index)

Now the expression:

   let index = index

means that you assign index to itself (not the outer index). That's not really a problem in a functional programming language, although it becomes problematic if you want to use such function.

like image 41
Willem Van Onsem Avatar answered Jul 21 '26 20:07

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!