이 Haskell 코드에서 "무한 유형"오류가 발생하는 이유는 무엇입니까?
저는 Haskell을 처음 접했고 이해할 수없는 "무한 유형을 구성 할 수 없습니다"라는 오류에 직면했습니다.
사실 그 이상으로이 오류가 무엇을 의미하는지에 대한 좋은 설명을 찾을 수 없었기 때문에 기본 질문을 넘어서 "무한 유형"오류에 대해 설명해 주시면 정말 감사하겠습니다.
코드는 다음과 같습니다.
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.
감사.
-
다음은 Haskell의 "무한 유형"오류를 처리하기위한 수정 된 코드와 일반적인 지침입니다.
수정 된 코드
intersperse _ [] = []
intersperse _ [x] = x
intersperse s (x:xs) = x ++ s:intersperse s xs
문제 :
내 타입 시그니처는 두 번째 매개 변수가 목록의 목록이라고 말한다. 따라서 "s (x : y : xs)"에 대해 패턴 매칭을했을 때 x와 y는 목록 이되었습니다 . 그러나 나는 x와 y를 목록이 아닌 요소로 취급했습니다.
"무한 유형"오류 처리 지침 :
대부분의 경우이 오류가 발생하면 다루고있는 다양한 변수의 유형을 잊어 버리고 변수가있는 것과 다른 유형 인 것처럼 사용하려고 시도한 것입니다. 모든 것이 어떤 유형인지, 어떻게 사용하는지주의 깊게 살펴보면 일반적으로 문제가 발견됩니다.
문제는 마지막 절에 있습니다. 여기서 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
종종 명시 적 유형 정의를 추가하면 컴파일러의 유형 오류 메시지가 더 의미가있을 수 있습니다. 그러나이 경우 명시적인 타이핑은 컴파일러의 오류 메시지를 더 악화시킵니다.
ghc가 intersperse의 유형을 추측하게하면 어떻게되는지보세요.
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'
그것은 분명히 코드의 버그를 가리 킵니다. 이 기술을 사용하면 다른 사람들이 제안한 것처럼 모든 것을 응시하고 유형에 대해 열심히 생각할 필요가 없습니다.
I may be wrong, but it seems you're trying to solve a more difficult problem. Your version of intersperse doesn't just intersperse the value with the array, but also flattens it one level.
The List module in Haskell actually provides an intersperse function. It puts in the value given between every element in the list. For example:
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"]
I'm assuming this is what you want to do because it's what my professor wanted us to do when I was learning Haskell. I could, of course, be totally out.
Also I found this which explains the meaning of the error.
Every time the interpreter/compiler gives me this error it's because I'm using some type-parametrized tuple as formal parameter. Everything works correctly by removing the type definition of the function, which was containing type variables.
I still cannot figure out how to both fix it and keep the function type definition.
'IT박스' 카테고리의 다른 글
| PHP의 비동기 함수 호출 (0) | 2020.10.25 |
|---|---|
| HTTP OPTIONS 요청에 응답하는 방법은 무엇입니까? (0) | 2020.10.25 |
| Java / Scala를 사용하여 HTML로 마크 다운 (0) | 2020.10.25 |
| 웹 서비스에서 HTML 문서를 어떻게 인쇄합니까? (0) | 2020.10.25 |
| Stripe-가입시 신용 카드없이 무료 요금제로 구독을 처리하는 방법 (0) | 2020.10.25 |