haskelltypesoption-typetype-signature

Troubles understanding why maybe type signature in Haskell


Hi I am having troubles understanding the type signature that I need for my function.

-- findPassword :: Map.Map Hash Passwd -> Int -> Hash -> Maybe Passwd
findPassword rTable width hashVal = do
    let usefulHashes = take (width+1) (iterate (pwHash.pwReduce) hashVal)
    let hashesInMap = [i | i <- usefulHashes, Map.member i rTable]
    let goodPass = [ rTable Map.! j | j <- hashesInMap]
    let findPass = listToMaybe [ helper k hashVal width | k <- goodPass, (helper k hashVal width) /= "" ] 
    return findPass
    where
        helper :: Passwd -> Hash -> Int -> Passwd
        helper passW hashVal width
            | (pwHash passW) == hashVal   = passW
            | width == 0                  = ""
            | otherwise                   = helper (pwReduce (pwHash passW)) hashVal (width-1)

In this function I take a table which is a map of Hash values (Int32) as keys to passwords (Strings) and attempt to find a given hash in the table. Once I find the password that I am looking for I use listToMaybe and return the value as a maybe Passwd. However, When I run this I receive this error:

* Couldn't match type `Maybe Passwd' with `[Char]'
      Expected type: Maybe Passwd
        Actual type: Maybe (Maybe Passwd)
    * In a stmt of a 'do' block: return result
      In the expression:
        do let usefulHashes
                 = take (width + 1) (iterate (pwHash . pwReduce) hashVal)
           let hashesInMap = ...
           let goodPass = ...
           let findPass = ...
           ....
      In an equation for `findPassword':
          findPassword rTable width hashVal
            = do let usefulHashes = ...
                 let hashesInMap = ...
                 let goodPass = ...
                 ....
            where
                turntoMaybe :: [Passwd] -> Maybe Passwd
                turntoMaybe list = listToMaybe list
                helper :: Passwd -> Hash -> Int -> Passwd
                helper passW hashVal width
                  | (pwHash passW) == hashVal = passW
                  | width == 0 = ""
                  | otherwise = helper (pwReduce (pwHash passW)) hashVal (width - 1)
   |
78 |     return result

So my question is why is it expecting a Maybe (Maybe Passwd) value? If i switch the type signature to Maybe (Maybe Passwd) it works but the output is expect a double Just Just "Passwd". If I remove the type signature it works just fine though. This is just a small snippet of the rest of the project so let me know if any clarifications is needed on it.


Solution

  • Haskell isn't Java. You're not supposed to end everything with a return. To get it to work, just change return findPass to findPass. You should also consider dropping the redundant do block and just using where instead of all of your lets.