2010-01-26 2 views

답변

4

이 작동하고 무엇이 필요합니까 :

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 
+1

'\\ _ -> False'는'const False'라고 쓸 수 있습니다. 스타일 론적으로, 나는 후자가 더 나은 의도를 가지고 있다고 믿지만, 사실상 동등하다. – ephemient

6

아니요,이 작업을 수행 할 방법이 없습니다 (여기서는 전혀 안전하지 않은 안전하지 않은 트릭).

BTW doesFileExist x == True은 모두 doesFileExist x으로 작성하는 것이 좋습니다.

18

당신은 이미 IO 모나드에 있습니다. 그럼 다음을 사용하지 않으시겠습니까? 실용적 선 (善)을 위해

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 <$> doesFileExist x 

의 실용적 경로가 더욱 가드보다 간결 당신은 당신의 질문에 사용하고 싶습니다!

3

보호 절의 유형은 Bool이어야합니다. doesFileExist x의 유형은 IO Bool입니다. 유형 불일치는 당신이 그렇게 할 수 없다는 것을 의미합니다.

+2

이것은 실제로 아무 의미도 없습니다. 'getLine'의 타입은'IO String'입니다. '(++ "foo")'의 타입은'String -> String'입니다. 그러나 올바른 결합자를 사용하여'getLine'을'(++ "foo")'에 넣을 수 있습니다. ('+++ foo ') $ getLine' 대신'get (++'foo ") <$> getLine을 써야합니다. 그래서이 질문에 대한 대답은 당신의 게시물이 누군가를 믿도록 이끌어 줄만큼 간단하지 않습니다. 단어 "아니요"실제로 귀하의 게시물보다 정확합니다.) – jrockway

+2

나는 당신의 요점을 이해하고 있는지 모르겠다. 나는 당신이'IO Bool'에서'Bool'을 어떻게 조합기를 사용하여 얻을 것으로 예상하는지 모르겠습니다. 당신이'unsafePerformIO'를 사용하여'IO Bool'에서'Bool'을 얻을 수는 있지만, 그러지 마십시오. 가드 절에는'Bool' 표현식이 필요하고 다른 표현식은 필요하지 않습니다. 나는 놓쳤습니까? 예상되는 형식이 무엇이고 주어진 형식이 무엇인지에 대한 설명이 아닌 "아니오"한 단어가 더 정확합니까? – yfeldblum

+0

@jrockway yfeldblum이 맞습니다. 'IO'의 전체 * 점은 'IO a'를'a'로 변환 할 방법이 없습니다. 올바른 결합자를 사용하여'getLine'에'(++ "foo")'를 적용하면'IO'에서'getLine'을 가져 와서 그것'Str '(''++'foo ')''타입에 적합하도록''++'foo '''**를''IO''에 넣고''getLine''의 타입에 맞 춥니 다. '(++ "foo") <$> getLine'을'String'을 사용할 수있는 곳으로 사용할 방법이 없으며 이것은 의도적으로 설계된 것입니다. 'Bool'이 필요한 곳에서는'IO Bool'의 값을 사용할 방법이 없습니다. – Ben