참고 :sprint
않습니다 하지 WHNF에 식을 줄일 수 있습니다. 그렇다면 다음이 4
아니라 오히려 줄 것입니다 _
.
Prelude> let four = 2 + 2 :: Int
Prelude> :sprint four
four = _
오히려, :sprint
바인딩의 이름을 취하고 바인딩 값의 내부 표현을 가로 지르며 사용하는 동안 이미 "평가 된 부분"(즉, 생성자 인 부분)을 보여줍니다._
되지 않은 썽크 (즉, 일시 중단 된 게으른 함수)의 자리 표시 자로 통화). 값이 완전히 평가되지 않으면 WHNF가 아닌 평가가 수행되지 않습니다. (그리고 값이 완전히 평가되면 WHNF뿐만 아니라 얻을 수 있습니다.)
실험에서 관찰하는 것은 다형성 대 단수 숫자 유형, 문자열 리터럴에 대한 다른 내부 표현 대 명시적인 문자 목록 등의 조합입니다. 기본적으로 서로 다른 리터럴 표현식이 바이트 코드로 컴파일되는 방식의 기술적 차이를 관찰하고 있습니다. 따라서 이러한 구현 세부 사항을 WHNF와 관련이 있다고 해석하면 절망적으로 혼동 될 것입니다. 일반적으로:sprint
WHNF 및 Haskell 평가의 의미에 대해 배우는 방법이 아니라 디버깅 도구로만 .
실제로 :sprint
수행중인 작업 을 이해 하려면 GHCi에서 몇 가지 플래그를 설정하여 표현식이 실제로 처리되는 방식을 확인하고 결국 바이트 코드로 컴파일 할 수 있습니다.
> :set -ddump-simpl -dsuppress-all -dsuppress-uniques
이 후, 우리는 당신의 이유를 볼 수 있습니다 intlist
제공_
:
> let intlist = [[1,2],[2,3]]
==================== Simplified expression ====================
returnIO
(: ((\ @ a $dNum ->
: (: (fromInteger $dNum 1) (: (fromInteger $dNum 2) []))
(: (: (fromInteger $dNum 2) (: (fromInteger $dNum 3) [])) []))
`cast` <Co:10>)
[])
당신은 무시할 수 있습니다 returnIO
외부 :
전화를 시작 부분에 집중할((\ @ a $dNum -> ...
다음 $dNum
은 Num
제약 조건 사전입니다 . 이는 생성 된 코드가 아직 type의 실제 유형 a
을 해석하지 않았 Num a => [[a]]
으므로 전체 표현식은 여전히 적절한 ((사전)) 함수를 호출하는 함수 호출로 표시됩니다.Num
유형 . 다시 말해, 그것은 평가되지 않은 썽크이며 우리는 다음을 얻습니다.
> :sprint intlist
_
반면에 유형을 다음과 같이 지정하십시오. Int
하면 코드가 완전히 다릅니다.
> let intlist = [[1::Int,2],[2,3]]
==================== Simplified expression ====================
returnIO
(: ((: (: (I# 1#) (: (I# 2#) []))
(: (: (I# 2#) (: (I# 3#) [])) []))
`cast` <Co:6>)
[])
그리고 역시 :sprint
출력도 :
> :sprint intlist
intlist = [[1,2],[2,3]]
마찬가지로 리터럴 문자열과 명시 적 문자 목록은 완전히 다른 표현을 갖습니다.
> let stringlist = ["hi", "there"]
==================== Simplified expression ====================
returnIO
(: ((: (unpackCString# "hi"#) (: (unpackCString# "there"#) []))
`cast` <Co:6>)
[])
> let charlist = [['h','i'], ['t','h','e','r','e']]
==================== Simplified expression ====================
returnIO
(: ((: (: (C# 'h'#) (: (C# 'i'#) []))
(: (: (C# 't'#)
(: (C# 'h'#) (: (C# 'e'#) (: (C# 'r'#) (: (C# 'e'#) [])))))
[]))
`cast` <Co:6>)
[])
:sprint
출력 의 차이는 GHCi가 평가 (명시 적 :
생성자) 대 평가되지 않은 ( unpackCString#
썽크) 표현의 일부를 아티팩트로 나타냅니다 .