2011-04-28 5 views
0

이 코드에 어떤 문제가 있습니까?다음 프로그램에 어떤 문제가 있습니까?

module Main where 
import System.Environment 
main :: IO() 
main = do 
    args <- getArgs 
    putStrLn ("Hello, " ++ args !! 0 ++ ", " ++ args !! 1) 
    putStrLn(add (read args !! 0) (read args !! 1)) 
add x y = x + y 

다음은 오류 메시지입니다 :

main.hs:8:15: 
    No instance for (Num String) 
     arising from a use of `add' 
    Possible fix: add an instance declaration for (Num String) 
    In the first argument of `putStrLn', namely 
     `(add (read args !! 0) (read args !! 1))' 
    In the expression: putStrLn (add (read args !! 0) (read args !! 1)) 
    In the expression: 
     do { args <- getArgs; 
      putStrLn ("Hello, " ++ args !! 0 ++ ", " ++ args !! 1); 
      putStrLn (add (read args !! 0) (read args !! 1)) } 

main.hs:8:25: 
    Couldn't match expected type `Char' with actual type `[Char]' 
    Expected type: String 
     Actual type: [String] 
    In the first argument of `read', namely `args' 
    In the first argument of `(!!)', namely `read args' 
+0

글쎄, 뭐가 잘못 됐어? 오류? – deceze

답변

8

read args !! 0read (args !! 0)해야하며 add x y = x +add x y = x + y을해야합니다. 또한 putStrLn은 문자열만을 사용하기 때문에 대신 숫자를 인쇄하는 print을 사용하십시오.


그러나 haskell을 처음 접하는 분입니다. 나는 프로그램의 일부를 다시 작성하여 더 악의적 인 방법을 보여주었습니다.

main = do 
    (arg0:arg1:restArgs) <- getArgs 
    putStrLn $ "Hello, " ++ arg0 ++ ", " ++ arg1 
    print $ add (read arg0) (read arg1) 
add = (+) 

이제 조금 더 깨끗해 보입니다. !!을 사용하는 것이 가장 바람직하지 않은 것으로 간주됩니다.

+1

'add'의 점없는 버전에서'x y'를 제거해야합니다. 그렇지 않으면 좋은 대답, +1. – interjay

+0

바로 그거야. 코드를 컴파일하지 않아도 죄송합니다. :) – Tarrasch

+0

진짜 이유는'!!'는 바람직하지 않은 오류 처리가 있기 때문에 나쁜 습관이라고 생각합니다. 또한 목록에서 패턴 매칭을 사용하는 것이'!!'를 사용하는 것보다 더 간결하지만 위험한 오류 동작은 똑같습니다. – mightybyte

3

오류 메시지와 해결 방법에 약간의 정교함을 추가하십시오. 첫 번째 오류를 살펴보면 :

 
    No instance for (Num String) 
    ... 
    In the first argument of `putStrLn' 

약간의 차이가있을 수 있습니다. putStrLn의 유형 서명에서보세요 :

 
putStrLn :: String -> IO() 

그래서, putStrLn은 문자열을 사용하고 IO 조치로 평가되는 기능입니다. 그러나 당신은 직접 을 putStrLn (x + y)와 같은 숫자 ()와 문자열이 숫자가 아닌 수식을 전달하려고 시도했습니다. (하스켈 용어로 타입 서명은 (Num t) => t입니다.)

대신 인쇄 기능을 이용하여 제안 상기 주어진 용액 :

 
print :: (Show a) => a -> IO() 

'인쇄'및 'putStrLn'사이의 차이가 인쇄 번호를 포함 showable 것을 취할 수있다. 최대

다음 :

 
    Couldn't match expected type `Char' with actual type `[Char]' 
    Expected type: String 
     Actual type: [String] 
    In the first argument of `read', namely `args' 

컴파일러가 읽을 수있는 첫 번째 인수로 문자열을 예상하지만, 문자열의 목록을보고 말한다. 읽기의 응용 프로그램이 높은 결합하는 것을 특히

 
(read args) !! 0 

(주 : 원래의 코드를 보면 : 컴파일러가 기본적으로 너무 같은 코드를 읽을 수 있도록 하스켈에서

 
read args !! 0 

, 기능 응용 프로그램은, 가장 높은 우선 순위를 가지고 !! 연산자의 사용보다). 다행히도 읽기가 모든 args에 적용 되었음이 분명해야합니다. 당신의 의도는 인수의 첫 번째 요소를 읽는 것 같았다으로

, 당신과 같이 괄호를 사용해야합니다

희망이 조금 더 이해할 수있는 오류 메시지를 만든다!

관련 문제