제목에서 알 수 있듯이 Haskell 함수 반환 단위를 평가하려면 어떤 보증이 있습니까? 그러한 경우에는 어떤 종류의 평가도 실행할 필요가 없다고 생각할 것입니다. ()
엄격한 요구가 명시되어 있지 않으면 컴파일러는 그러한 모든 호출을 즉시 값으로 바꿀 수 있습니다. 반품 ()
또는 하단.
나는 GHCi에서 이것을 실험했고, 그 반대의 일, 즉 그러한 기능이 평가 된 것처럼 보입니다. 매우 원시적 인 예는
f :: a -> ()
f _ = undefined
f 1
의 존재로 평가 하면 오류가 발생 undefined
하므로 일부 평가는 확실히 발생합니다. 그러나 평가가 얼마나 깊이 진행되는지는 확실하지 않습니다. 때로는 함수를 호출하는 모든 호출을 평가하는 데 필요한만큼 깊이있는 것처럼 보입니다 ()
. 예:
g :: [a] -> ()
g [] = ()
g (_:xs) = g xs
이 코드는로 표시되면 무한정 반복됩니다 g (let x = 1:x in x)
. 하지만
f :: a -> ()
f _ = undefined
h :: a -> ()
h _ = ()
는 h (f 1)
returns 를 표시하는 데 사용할 수 ()
있으므로이 경우 모든 단위 값 하위 표현식이 평가되는 것은 아닙니다. 여기서 일반적인 규칙은 무엇입니까?
ETA : 물론 게으름에 대해 알고 있습니다. 컴파일러 작성자 가이 특별한 경우를 평소보다 더 게으르게 만드는 것을 막고 있습니다.
ETA2 : 예제 요약 : GHC는 ()
다른 유형과 똑같이 취급 하는 것으로 보입니다 . 즉, 유형에 거주하는 규칙적인 값이 함수에서 반환되어야하는 문제가있는 것처럼 보입니다 . 그러한 값이 하나만 있다는 사실은 최적화 알고리즘에 의해 사용되지 않는 것 같습니다.
ETA3 : Haskell을 말할 때, 나는 Haskell-H-in-GHC가 아니라 보고서에 의해 정의 된 Haskell을 의미합니다. 내가 상상했던 것 ( '독자의 100 %에 의한 것')만큼 널리 공유되지 않은 가정 인 것 같거나, 아마도 더 명확한 질문을 공식화 할 수 있었을 것이다. 그럼에도 불구하고, 나는 원래 그 함수가 호출되는 것에 대해 어떤 보증 이 있는지 묻기 때문에 질문의 제목을 바꾸는 것을 후회합니다 .
ETA4 :이 질문에 대한 답이 나오고있는 것 같습니다. ( '닫는 질문'기능을 찾고 있었지만 '자신의 질문에 대한 답변'만 찾았으며 답을 찾을 수 없으므로 해당 경로를 따라 가지 않았습니다.) 아무도 보고서에서 어떤 방법 으로든 결정하지 않은 것을 제기하지 않았습니다. 나는 강력하지만 확실하지 않은 '언어를 보장하지 않습니다'라는 대답으로 해석하고 싶어합니다. 우리가 아는 것은 현재 GHC 구현이 그러한 기능의 평가를 생략하지 않는다는 것입니다.
OCaml 앱을 Haskell에 이식 할 때 실제 문제가 발생했습니다. 원래 앱에는 여러 유형의 상호 재귀 구조가 있었고 코드는 assert_structureN_is_correct
1..6 또는 7에서 N을 호출하는 여러 함수를 선언했습니다 . 각 함수 는 구조가 실제로 정확하면 단위를 반환하고 그렇지 않은 경우 예외를 던졌습니다. . 또한 이러한 기능은 정확성 조건을 분해 할 때 서로 호출되었습니다. Haskell에서는 Either String
모나드를 사용하여 처리하는 것이 더 좋았 으므로 필자는 그렇게했지만 이론적 인 문제로 남아 있습니다. 모든 의견과 답변에 감사드립니다.
f 1
의해 "대체"됩니다 undefined
.
... -> ()
는 1) 종료 및 리턴 ()
, 2) 예외 / 런타임 오류로 종료하고 아무것도 리턴하지 못하거나 3) 분기 (무한 재귀) 할 수 있습니다. GHC는 1) 발생할 수 있다고 가정하여 코드를 최적화하지 않습니다. f 1
요구되는 경우 평가 및 리턴을 건너 뛰지 않습니다 ()
. Haskell 시맨틱은이를 평가하고 1,2,3 사이에 어떤 일이 발생하는지 확인하는 것입니다.
()
이 질문에는 (유형이나 값) 특별한 것이 없습니다 . () :: ()
예를 들어 0 :: Int
어디에서나 교체하면 동일한 결과가 나타납니다 . 이것들은 모두 게으른 평가의 오래된 지루한 결과입니다.
()
유형, ()
및 undefined
.
h1::()->() ; h1 () = ()
하고h2::()->() ; h2 _ = ()
. 모두를 실행h1 (f 1)
하고h2 (f 1)
, 그 첫 번째 하나의 요구 사항을 참조하십시오(f 1)
.