2013-10-18 2 views
1

에 대한 오류를보고하는 방법이 여기 내 마지막 질문에 대한 확장입니다 : 유효하지 않은 입력이 첨가되어 그러나 때 basic haskell : Copying elements하스켈 : 내 기능

내가 그것을 말하는 오류 메시지를 인쇄 할 "음의 값" 또는 비슷한 것. 이게 가능하니? 작업 코드 :

copy :: Int->a->[a] 
copy 0 _ = [] 
copy y a = [a]++(copy (y-1) a) 

마지막 줄 :

copy b c = error "negative value" 
+2

"잘못된 입력"을 정의하십시오. (또한 실제 질문에 대한 대답은 "예"입니다.) –

+1

'error'를 호출하면 프로그램이 오류 메시지와 함께 중단됩니다. 함수의 반환 유형 (즉 :'String [a]'또는'Maybe [a]')에서 에러를 인코딩 한 다음, 함수에서 각각 "Left err"또는 "Nothing"을 확인해야합니다. 'copy'를 호출합니다. –

답변

6

, 우리가 스왑 아웃 한

copy :: Int -> a -> Maybe [a] 
copy 0 _ = Just [] 
copy n a | n < 0 = Nothing 
     | otherwise = fmap (a:) (copy (n-1) a) 

의 라인을 따라 뭔가 더

foo bar | baz = quux 
     | ... 

그냥하는 "보호"에 대한 if 있다고하고 좋을 것

foo bar = if baz then quux else ... 

코드도 약간 변경되었습니다.

[a] ++ copy (y-1) a ====> fmap (a:) (copy (y-1) a) 

(:)을 추가로 생각할 수 있습니다.

1 : [2, 3] ==> [1, 2, 3] 

[1] ++ [2, 3]의 대체 방법입니다. "구조물"처럼 "죄수"라고 소리내어 말하십시오. 우리는 이것을 연산자 섹션으로 쓸 수 있습니다

(a:) ==> \x -> a : x 

다음으로 우리는이 우키 한 fmap 함수를 사용합니다. 이

fmap f Nothing = Nothing 
fmap f (Just x) = Just (f x) 

처럼 fmap 생각은 그래서는 Just을 펼쳤다하고 결과를 재배치하기 전에 기능을 적용합니다. 따라서 숫자가 음수이면 최종 코드는 Nothing을 반환하고, 그렇지 않으면 목록 만 반환합니다.

내가 추천하지 않는 이유는 무엇입니까 error?자, error은 아주 간단한 정보로 전체 프로그램을 날려 버릴 것이고 그것을 잡으려고하는 것은 나쁜 생각입니다. Haskell은 그렇게 할 수 있다고 명령하지도 않으며, GHC는 단지 error을 가능하게 구현합니다. 즉, 회복 할 기회가 거의 없습니다.

이것은 10 줄의 코드에는 큰 문제가 아니지만 error을 사용하는 함수 호출에 대한 검색에는 6 시간 이상을 소비했습니다. 디버깅이 훨씬 빠르며 관용적 인 haskell이 더 빠릅니다.

+1

+1 단계별 설명으로 초보자 친화적 인 단계. –

-6

모습 예를 들어 http://www.haskell.org/haskellwiki/Error_vs._Exception

에서이

copy b c = if c > b then error "negativ value" 
+1

'if' 표현식의'else' 부분은 선택 적이 지 않습니다. 또한,'[c] ++'보다는'c :'를 사용해야합니다. – duplode

+3

이것이 왜 이것이 대답인지 이해할 수 없습니다. 이 예제는 유효한 구문이 아닙니다. 'b'와 'c'는 서로 비교할 수 없습니다. –

+1

@LambdaFairy와 'negative'는 철자가 틀린 것입니다. – DiegoNolan

1

당신은 경비원이 작업을 수행 할 수

copy :: Int -> a -> [a] 
copy n x 
    | n < 0 = error "negative value" 
    | n == 0 = [] 
    | otherwise = x : copy (n - 1) x 

그러나 실패 할 경우 프로그램이 중단 될 수 있습니다.

copySafe :: Int -> a -> Maybe [a] 
copySafe n x 
    | n < 0 = Nothing 
    | otherwise = Just (copy n x) 

그런 다음 당신은 당신이 copySafe의 두 가지 경우를 고려하는

main = do 
    putStrLn "Enter a number:" 
    nStr <- getLine 
    let n = read nStr :: Int 
     maybeXs = copySafe n n 
    case maybeXs of 
     Nothing -> putStrLn "You entered a negative number!" 
     Just xs -> print xs 

으로이 스타일의 힘을 사용할 수 있습니다, 하나는 음의 값에 실패하거나 수 있습니다 더 좋은 방법은 Maybe 유형을 사용하는 것입니다 유효한 목록을 반환 할 수 있습니다. 프로그램을 크래시하지 않으며 오류 처리가 유형 시스템에 의해 시행됩니다. 일부 기능이 나를 슬프게 때문에

+0

다른 방법이 아닌'copy'를'copySafe'로 정의 할 것을 제안합니다. –

+0

@LambdaFairy 나도 그렇 겠지만, 나는이 예제에서'fmap'을 멀리하고 싶었다. – bheklilr