在Haskell中,有没有一种方法可以在函数保护中执行IO?
例如:在Haskell中,有没有一种方法可以在函数保护中执行IO?,haskell,io,guard,Haskell,Io,Guard,例如: newfile :: FilePath -> IO Bool newfile x | length x <= 0 = return False | doesFileExist x == True = return False | otherwise = return True newfile::FilePath->IO Bool newfile x | length x不,没有办法做到这一点(这里没有完全不合适的不安全技巧) 顺便说一
newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
| doesFileExist x == True = return False
| otherwise = return True
newfile::FilePath->IO Bool
newfile x | length x不,没有办法做到这一点(这里没有完全不合适的不安全技巧)
顺便说一句,如果可能的话,doesFileExist x==True
编写为doesFileExist x
会更好。您已经在IO
单子中了,那么为什么不使用以下命令呢
newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
| otherwise = do exists <- doesFileExist x
return $ not exists
newfile::FilePath->IO Bool
newfile x | length x保护子句的类型必须是Bool
。doesFileExist x
的类型是IO Bool
。类型不匹配意味着您无法执行此操作。此操作有效,并执行所需的操作:
newfile :: FilePath -> IO Bool
newfile fn = do
x <- runErrorT $ do
when ((length fn) <= 0) (throwError "Empty filename")
dfe <- liftIO $ doesFileExist fn
when (dfe) (throwError "File already exists")
return True
return $ either (\_ -> False) id x
newfile::FilePath->IO Bool
newfile fn=do
我相信这是一个编辑的问题,而不是一个独立的问题。这并不意味着什么。getLine
的类型是IO字符串
。(++“foo”)
的类型是String->String
。但是您仍然可以使用正确的组合符将getLine
馈送到(++“foo”)
。(也就是说,(++“foo”)getLine
,而不是(++“foo”)$getLine
。所以这个问题的答案并不像你的帖子可能让人相信的那么简单。(实际上,我认为“不”这个词比你的帖子更正确。)我不确定我是否理解你的观点。我不确定你希望如何使用组合符从IO Bool
中得到Bool
。虽然你可以使用unsafePerformIO
从IO Bool
中得到Bool,但请不要。除此之外,保护子句需要Bool
表达式,而不是表达式任何其他类型的失言。那么我错过了什么?一个“不”字怎么样更正确,而不是解释什么是预期类型和什么是给定类型?@jrockway yfeldblum是正确的。IO
的全部要点是没有办法将IO a
转换为a
。使用正确的组合符应用(++“foo”)
togetLine
不会将getLine
从IO
中拉出,使其成为字符串
,因此它适合(++“foo”)
,它会将(++“foo”)
放入IO
中,使其适合getLine
的类型。无法使用(++“foo”)getLine
,您希望能够使用字符串,这是经过设计的。在需要Bool
的情况下,也没有办法使用IO Bool
值。\\\\\\\\->False
可以编写const False
。从风格上来说,我相信后者更能体现意图,但它实际上是一种有效的方法同等的。
newfile :: FilePath -> IO Bool
newfile fn = do
x <- runErrorT $ do
when ((length fn) <= 0) (throwError "Empty filename")
dfe <- liftIO $ doesFileExist fn
when (dfe) (throwError "File already exists")
return True
return $ either (\_ -> False) id x