2009-04-27 12 views
59

나는 하스켈을 처음 접했고 "무한한 타입을 만들 수 없다"라는 오류에 직면했다.왜이 하스켈 코드가 "무한 타입"오류를 생성합니까?

실제로이 오류가 무엇을 의미하는지에 대한 좋은 설명을 찾을 수 없었기 때문에 기본 질문을 뛰어 넘어 "무한 유형"오류에 대해 설명해 주시면 감사하겠습니다. 그것.

여기에 코드입니다 :

intersperse :: a -> [[a]] -> [a] 

-- intersperse '*' ["foo","bar","baz","quux"] 
-- should produce the following: 
-- "foo*bar*baz*quux" 

-- intersperse -99 [ [1,2,3],[4,5,6],[7,8,9]] 
-- should produce the following: 
-- [1,2,3,-99,4,5,6,-99,7,8,9] 

intersperse _ [] = [] 
intersperse _ [x] = x 
intersperse s (x:y:xs) = x:s:y:intersperse s xs 

그리고 여기 인터프리터에로드하려고 오류입니다 :

Prelude> :load ./chapter.3.ending.real.world.haskell.exercises.hs 
[1 of 1] Compiling Main (chapter.3.ending.real.world.haskell.exercises.hs, interpreted) 

chapter.3.ending.real.world.haskell.exercises.hs:147:0: 
Occurs check: cannot construct the infinite type: a = [a] 
When generalising the type(s) for `intersperse' 
Failed, modules loaded: none. 

감사합니다.

수정 코드

intersperse _ [] = [] 
intersperse _ [x] = x 
intersperse s (x:xs) = x ++ s:intersperse s xs 

무엇을 : -

여기

는 일부 코드와 하스켈에서 "무한 유형"오류 처리에 대한 일반적인 가이드 라인을 수정입니다 문제는 다음과 같습니다.

내 서명 서명 상태 intersperse에 대한 두 번째 매개 변수는 목록의 목록입니다. 따라서 "(x : y : xs)"와 패턴이 일치하면 x와 y는 이되고이됩니다. 그리고 x와 y를 원소가 아닌리스트로 취급하고있었습니다. 은 "무한 유형"오류를 처리하는

가이드 라인 :

이 오류를 얻을 때 대부분의 시간, 당신은 당신이 상대하고있는 다양한 변수의 종류를 잊어하고있다 변수를 다른 유형처럼 사용하려고했습니다. 모든 유형의 사용법과 사용 방식을주의 깊게 살피십시오. 그러면 일반적으로 문제가 발견됩니다.

+1

또 다른 유용한 팁 : 유형을 명시 적으로 선언하십시오. 이렇게하면 컴파일러가 확인할 내용을 제공합니다. –

+1

그래서 문제가 해결되지만 컴파일러에서 "무한 타입을 생성 할 수 없습니까?"라고 말하는 이유는 무엇입니까? 그게 무슨 뜻 이죠? 문제가 이러한 연산을 지원하지 않는 유형의 연산을 수행하려고한다면 컴파일러가 그런 식으로 말하지 않는 이유는 무엇입니까? – freedrull

+9

질문 구조 (질문 - 정정 - 문제 - 지침)에 대한 +1 – Dacav

답변

27

문제는 마지막 절에서 x 및 y를 요소로 취급하며 목록 인 반면 문제가됩니다. 이것은 작동합니다 :

intersperse _ [] = [] 
intersperse _ [x] = x 
intersperse s (x:y:xs) = x ++ [s] ++ y ++ intersperse s xs 

무한 유형의 오류가 발생하는 이유는 운영자가 입력되어있는 -> [A] -> [A], 당신이로 취급하면서 [A] -> A -> [A] 이는 [a]가 a로 식별되어야 함을 의미하며, 이는 a가 무한대로 중첩 된 목록임을 의미합니다. 그건 허용되지 않습니다 (어쨌든, 당신이 의미하는 것이 아닙니다).

편집 : 위의 코드에 또 다른 버그가 있습니다.

intersperse _ [] = [] 
intersperse _ [x] = x 
intersperse s (x:xs) = x ++ [s] ++ intersperse s xs 
+0

감사합니다. 나는 그 두 사람 모두 밖으로 나왔다가 다시 여기에 와서 당신의 반응을 보았습니다. 그것은 나를위한 훌륭한 검증이었습니다. 너는 내 버그를 내가 한 것보다 더 잘 고쳤다. 내 버그는 y와 x 사이의 구분 기호를 건너 뛰는 것이 었습니다. 이 문제를 해결하기 위해 다음과 같은 또 다른 수준의 패턴 일치를 도입했습니다. intersperse s (x : y : []) = x ++ s : y intersperse s (x : y : xs) = intersperse s [x, y] ++ s : intersperse s xs 하지만 추가 레벨을 필요로하지 않고 버그를 고쳤습니다. –

+1

다음은 내가 배운 교훈입니다. "무한한 유형의 오류에 직면 할 때, 당신은 아마도 당신이 상대하고있는 유형을 잊어 버리고 당신이하려고하지 않은 것을하고있을 것입니다. 변수가 있으며, 보통 문제를 밝혀 낼 것입니다. " 거기에 추가하거나 변경할 것이 있습니까? –

+0

그건 틀린 것이고, 나는 그것에 대해 아무것도 바꿀 수 없을 것입니다.무한 유형은 허용되지 않으므로 무한 유형 오류는 함수가 잘못된 유형의 인수를받는 어딘가를 의미합니다. RWH를 가진 행운을 빕니다 :) – Stephan202

2

내가 잘못 될 수있다, 그러나 당신이 더 어려운 문제를 해결하려는 것 같다 그것은해야합니다. intersperse 버전은 배열에 값을 삽입하는 것이 아니라 한 수준을 평평하게 만듭니다.

하스켈에있는 List 모듈은 실제로 intersperse 기능을 제공합니다. 이 값은 사이의 값으로 지정되며 목록의 각 요소는입니다.예를 들어 :

intersperse 11 [1, 3, 5, 7, 9] = [1, 11, 3, 11, 5, 11, 7, 11, 9] 
intersperse "*" ["foo","bar","baz","quux"] = ["foo", "*", "bar", "*", "baz", "*", "quux"] 

나는 이것이 당신이 내 교수는 내가 하스켈을 학습 할 때 우리가하고 싶었던 무엇 때문에하고 싶은 것입니다 있으리라 믿고있어. 나는 물론 완전히 벗어날 수 있었다.

+0

코멘트를위한 감사합니다. 그러나이 경우에는 "Real World Haskell"3 장 끝에서 연습 7을하고 있기 때문에 한 수준을 평평하게하고 싶습니다. –

+0

Gotcha. 내가 책을 가지고 있다면, 내가 썼기 전에 나는 확인했을 것이다. 아아, 내가 할 수 있었던 전부는 추측이었다. 어쨌든 다행히 다행 이군. :-) –

+4

이 책의 내용은 http://book.realworldhaskell.org/ – Stephan202

0

또한 오류의 의미를 설명하는 this을 발견했습니다.

인터프리터/컴파일러가 나에게이 오류를 표시 할 때마다 형식 매개 변수로 형식 매개 변수가있는 튜플을 사용하고 있기 때문입니다. 모든 것은 에 의해 올바르게 작동합니다. 형식 변수가 포함 된 함수의 형식 정의가 제거되었습니다.

나는 그것을 고치고 기능 유형 정의를 유지하는 방법을 아직 생각할 수 없다.

3

명시 적 형식 정의를 추가하면 컴파일러의 형식 오류 메시지가 더 적합해질 수 있습니다. 그러나이 경우 명시 적 입력은 컴파일러의 오류 메시지를 악화시킵니다.

내가 GHC는 산재의 유형을 추측 할 때 발생 봐 : 분명히 코드에서 버그를 향해 지적

Occurs check: cannot construct the infinite type: a = [a] 
    Expected type: [a] -> [[a]] -> [[a]] 
    Inferred type: [a] -> [[a]] -> [a] 
In the second argument of `(:)', namely `intersperse s xs' 
In the second argument of `(:)', namely `y : intersperse s xs' 

합니다. 이 기술을 사용하면 다른 사람들이 제안했듯이 모든 것을 응시하고 유형을 열심히 생각할 필요가 없습니다.

관련 문제