无法理解为什么可能在 Haskell 中键入签名

kss*_*sss 0 haskell types maybe type-signature

嗨,我在理解函数所需的类型签名时遇到了麻烦。

-- 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)
Run Code Online (Sandbox Code Playgroud)

在这个函数中,我将一个表,它是一个哈希值(Int32)映射作为密码(字符串)的键,并尝试在表中找到给定的哈希。一旦我找到了我正在寻找的密码,我就会使用 listToMaybe 并将该值作为可能的 Passwd 返回。但是,当我运行它时,我收到此错误:

* 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
Run Code Online (Sandbox Code Playgroud)

所以我的问题是为什么它期望一个 Maybe (Maybe Passwd) 值?如果我将类型签名切换为 Maybe (Maybe Passwd),它会工作,但输出预期是双倍的 Just Just "Passwd"。如果我删除类型签名,它就可以正常工作。这只是项目其余部分的一小部分,因此如果需要对其进行任何说明,请告诉我。

Jos*_*ica 7

Haskell 不是 Java。你不应该以return. 要使其工作,只需更改return findPassfindPass. 您还应该考虑删除冗余do块并只使用where而不是所有的lets。

  • @cksssssss Haskell 中没有 return 语句之类的东西。`return` 只是一个函数,没有理由期望对数据调用随机函数会做一些有用的事情。 (7认同)