在Haskell中,有没有办法在函数防护中进行IO?

发布于 2024-08-19 04:50:38 字数 217 浏览 15 评论 0原文

例如:

newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
          | doesFileExist x == True = return False
          | otherwise = return True

这可以工作吗?

For example:

newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
          | doesFileExist x == True = return False
          | otherwise = return True

Can this be made to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

望喜 2024-08-26 04:50:38

您已经在 IO monad 中,那么为什么不使用以下内容呢?

newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
          | otherwise = do exists <- doesFileExist x
                           return $ not exists

对于应用性的好处:

import Control.Applicative

newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
          | otherwise = not <
gt; doesFileExist x

正如您所看到的,应用性路线比您想在问题中使用的防护更加简洁!

You're already in the IO monad, so why not use the following?

newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
          | otherwise = do exists <- doesFileExist x
                           return $ not exists

For applicative goodness:

import Control.Applicative

newfile :: FilePath -> IO Bool
newfile x | length x <= 0 = return False
          | otherwise = not <
gt; doesFileExist x

As you can see, the applicative route is even more concise than the guards you'd like to use in your question!

蓝眸 2024-08-26 04:50:38

不,没有办法做到这一点(缺少不安全的技巧,这在这里是完全不合适的)。

顺便说一句,如果可能的话,doesFileExist x == True 最好写成 doesFileExist x

No, there's no way to do this (short of unsafe tricks which would be completely inappropriate here).

BTW doesFileExist x == True would be better written as doesFileExist x were it possible at all.

|煩躁 2024-08-26 04:50:38

这有效并完成了所需的操作:

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

This works and does what's needed:

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
属性 2024-08-26 04:50:38

保护子句的类型必须是BooldoesFileExist x的类型是IO Bool。类型不匹配意味着你不能这样做。

The type of guard clauses must be Bool. The type of doesFileExist x is IO Bool. The type mismatch means you can't do that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文