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.
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 let
s.