Not :sprintyok değil WHNF için bir ifade azaltır. Eğer öyleyse, aşağıdakiler 4yerine aşağıdakileri verecektir _:
Prelude> let four = 2 + 2 :: Int
Prelude> :sprint four
four = _
Aksine, :sprintbir bağlamanın adını alır, bağlamanın değerinin iç temsilini geçer ve _değerlendirilmemiş gövdeler için yer tutucu olarak (yani, askıya alınmış tembel işlev ) kullanılırken zaten "değerlendirilen parçaları" (yani, yapıcı olan parçaları) gösterir. ) çağırır. Değer tamamen değerlendirilmemişse, WHNF için bile hiçbir değerlendirme yapılmayacaktır. (Ve değer tamamen değerlendirilirse, bunu sadece WHNF değil, elde edersiniz.)
Deneylerinizde gözlemlediğiniz şey, polimorfik ve monomorfik sayısal tiplerin bir kombinasyonu, karakter dizileri için farklı dahili gösterimler ve açık karakter listeleri vb. Dolayısıyla, bu uygulama ayrıntılarını WHNF ile bir ilgisi olarak yorumlamak sizi umutsuzca şaşırtacak. Genel olarak, :sprintWHNF ve Haskell değerlendirmesinin anlambilimi hakkında bilgi edinmenin bir yolu olarak değil, yalnızca bir hata ayıklama aracı olarak kullanılmalıdır .
Gerçekten ne :sprintyaptığını anlamak istiyorsanız, ifadelerin gerçekte nasıl ele alındığını görmek için GHCi'de birkaç bayrağı açabilirsiniz ve sonunda bayt koduna derlenir:
> :set -ddump-simpl -dsuppress-all -dsuppress-uniques
Bundan sonra biz senin nedenini görebilirsiniz intlistverir _:
> 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>)
[])
returnIODış :çağrıyı ve dış çağrıyı görmezden gelebilir ve ile başlayan bölüme konsantre olabilirsiniz.((\ @ a $dNum -> ...
İşte $dNumiçin sözlük olan Numkısıtlaması. Oluşturulan kod henüz gerçek türü çözülmediği olduğu bu araçlar atürü Num a => [[a]]tüm ifade hala için (sözlük), uygun bir bir alarak bir işlev olarak temsil edilir, böylece Numtürü. Başka bir deyişle, değerlendirilmemiş bir thunk ve şunu elde ediyoruz:
> :sprint intlist
_
Öte yandan, türü olarak belirtin Intve kod tamamen farklıdır:
> let intlist = [[1::Int,2],[2,3]]
==================== Simplified expression ====================
returnIO
(: ((: (: (I# 1#) (: (I# 2#) []))
(: (: (I# 2#) (: (I# 3#) [])) []))
`cast` <Co:6>)
[])
ve böylece :sprintçıktı:
> :sprint intlist
intlist = [[1,2],[2,3]]
Benzer şekilde, değişmez dizeler ve açık karakter listeleri tamamen farklı temsillere sahiptir:
> 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>)
[])
ve :sprintçıktıdaki farklılıklar, GHCi ifadesinin hangi bölümlerinin değerlendirilmemiş (açık :kurucular) ile değerlendirilmemiş ( unpackCString#thunks) karşısındaki yapaylıkları temsil eder .