Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell中,有没有一种方法可以在函数保护中执行IO?_Haskell_Io_Guard - Fatal编程技术网

在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”)
to
getLine
不会将
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