2012-07-23 3 views
4

저는 Yesod와 Haskell을 처음 접하니 나와 함께 감당하십시오.하지만 파일을 받고, 단어를 세어보고 새로운 Yesod 웹 페이지에 결과를 보여주는 프로그램이 있습니다. 예외를보다 정상적으로 잡을 방법이 필요합니다. 예를 들어, 숨겨진 파일에 아래와 같은 기능을 실행하는 경우 :사이트를 죽이지 않고 Yesod 내에서 예외를 잡아낼 수 있습니까?

wordCount :: String -> String -> String 

wordCount ('.' : _) _ = error "Cannot count hidden files." 
wordCount name contents = "<p>There are <b>" ++ show (length $ words contents) ++ "</b> words in your file <i>" ++ name ++ "</i>.</p>" 

내가 그 오류 메시지를 표시 한 다음 새 파일을 제출하는 사용자에 대한 양식을 표시하고 싶습니다. 지금은 "페이지가로드되는 동안 서버에 대한 연결이 재설정되었습니다."라는 페이지로 이동합니다.

나는 Yesod가 내 자신의 것을 쓰기 위해 숨길 수있는 고유 한 catch 기능을 가지고 있다고 생각하지만, 어디서 왔는지는 확실치 않아 어떤 문서에서도 해당 내용을 찾을 수 없습니다. 사용자가 잘못된 파일을 넣으면 사이트가 충돌하는 것을 원하지 않습니다.

도움이 될 것입니다.

편집 : 제안 해 주셔서 감사합니다. 이 방법으로 오류를 던지면 오류를 처리하는 가장 좋은 방법이 아니라는 것을 알고 있습니다. 문제는 실제로 실제로 예스 사이트가 아닌 터미널에서 실행되는 기존 하스켈 코드로 작업하고 있다는 것입니다. 작은 예제로 wordcount를 사용했지만 실제로는 수십 가지 기능과 흩어져있는 오류 던져 버리는 수십 개의 파일입니다. 다행스럽게도 기존 코드의 모든 기능을 완전히 수정하지 않고도이를 포착 할 수 있습니다. 누구든지 Yesod에서 예외를 잡는 방법에 대한 제안이 있으면 정말 감사하겠습니다.

+2

그런 예외에 대해서는 '오류'를 사용하지 마십시오. 'Either ErrorMessage ReturnType' 또는 다른 에러 메커니즘을 사용하십시오. – dflemstr

+0

오류 메커니즘과 관련하여 최근 Hackage의 새로운 [errors] (http://www.haskellforall.com/2012/07/errors-10-simplified-error-handling.html) 패키지에 대한 멋진 블로그 게시물이있었습니다. 'Either','Maybe' 등을 이용한 기본적인 오류 처리 기법 –

답변

3

dflemstr이 말한 것처럼 복구 가능한 오류에는 error을 사용하지 마십시오. 오류 메커니즘은 undefined과 유사합니다. --it는 아직 작성되지 않은 함수 또는 무한 루프와 같이 완전히 치명적인 오류를 나타냅니다. 이 아닐 경우 부분적 기능을 수행하는 것이 좋습니다.이 나쁜 경우를 맞았지만 예상되는 오류를 처리하는 데는 최적이 아닙니다. 또한 유형 시스템에는 사용자의 error 사용이 반영되지 않으므로 기능을 사용하는 소비자는 오류를 인식 할 수있는 방법이 없습니다.

대신이 같은 오류를 나타내는 Maybe 또는 Either과 같은 유형을 사용해야합니다. 예를 들어, 그래서이 함수를 다시 작성할 수 :

wordCount :: String -> String -> Maybe String 
wordCount ('.' : _) _ = Nothing 
wordCount name contents = Just $ "<p>There are <b>" ++ show (length $ words contents) ++ "</b> words in your file <i>" ++ name ++ "</i>.</p>" 

자, 대신 String을 반환하는 당신이 Maybe String을 반환합니다. 이것은 Nothing 또는 Just String 중 하나 일 수 있습니다. Nothing은 실패를 나타냅니다. 즉, 입력이 유효하지 않아 함수가 실패했습니다. Just은 성공을 나타냅니다.

다음에 "캐치"오류 수행 할 수 있습니다 단지 패턴 일치 :

case wordCount fileName contents of 
    Just res -> res 
    Nothing -> "Cannot count hidden files!" 

일반적인 경우에 코드 깔끔한 모양을 만들 Data.Maybe에서 일부 편의 기능도 있습니다.

다른 옵션은 Either입니다. Maybe 유형의 경우 Nothing 생성자에는 추가 정보가 없습니다. 함수가 실패했다는 것만 알면됩니다. Either은 "실패"케이스를 제외하고 동일한 방식으로 작동합니다. 은 임의의 추가 정보를 전달합니다. "실패"케이스는 Left이고 "성공"케이스는 Right입니다.유형에는 오류 정보의 유형과 결과 유형의 두 가지 매개 변수도 있습니다. 그 결과는 다음과 같습니다

wordCount :: String -> String -> Either String String 
wordCount ('.' : _) _ = Left "You cannot count a hidden file!" 
wordCount name contents = Right $ "<p>There are <b>" ++ show (length $ words contents) ++ "</b> words in your file <i>" ++ name ++ "</i>.</p>" 

는 그런 다음 결과에게 Maybe와 동일한 방식으로 처리 할 수 ​​있습니다. 이 경우에는 함수가 실패 할 수있는 유일한 방법이 있기 때문에 Maybe이 바람직하다고 생각합니다. 가능한 오류 조건이 많으면 Either이 더 나은 선택입니다.

관련 문제