我有这个测试:
testReadFile = runTestTT $ TestLabel "InteractionDomain.readFileContentsToList" (TestList [
(TestLabel "testing infrastructure: read test file" (TestList [
TestCase (withTempFileContainingText (\fileHandle ->
assertEqual "contents as expected" "The dog barks at midnight." (do
content <- hGetContents fileHandle
return content)))]))])
并且(如果有帮助)withTempFileContainingText
就是这个函数
withTempFileContainingText lambda =
bracketOnError
(do (path, fileHandle) <- openTempFile "." "input.txt"
return fileHandle)
(deleteFile)
(\fileHandle -> do
hPutStr fileHandle "The dog barks at midnight."
hClose fileHandle --hoping this flushes buffers
return (lambda fileHandle))
ghc
提示说
InteractionDomain.hs:36:4: Couldn't match expected type `IO String' against inferred type `[String]' In a stmt of a 'do' expression: content ≤- hGetContents fileHandle
我不明白。为什么会推断content
是一个String列表?这段代码应该是什么样的?
最佳答案
嗯,我立即看到的是您的断言中的类型不匹配。
assertEqual 是 String -> a -> a -> Assertion
。您通过 String
作为第二个参数,意思是 String
也应该是第三个参数。然而,你的do
表达式未返回String
,而是IO String
。
编辑:要扩展,一旦你搞乱 IO
,你永远无法抛弃它。您可以使用 <-
正确地从 IO 中提取值,但随后立即将其包装回 IO
与 return
。如果要使用字符串,必须在 IO
内进行,类似:
do
contents <- hGetContents handle
assertEqual "They're equal" "Expected string" contents
请注意,然后您的 do
将返回 IO Assertion
。如果您想使用断言值,则需要以类似的方式将其解包,依此类推。 Haskell 不会让你摆脱(隐藏的)副作用!
关于haskell - 当代码中没有可见列表时,为什么推断类型是 [String]?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3287529/