Not :sprint
yok değil WHNF için bir ifade azaltır. Eğer öyleyse, aşağıdakiler 4
yerine aşağıdakileri verecektir _
:
Prelude> let four = 2 + 2 :: Int
Prelude> :sprint four
four = _
Aksine, :sprint
bir 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, :sprint
WHNF 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 :sprint
yaptığı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 intlist
verir _
:
> 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
Dış :
çağrıyı ve dış çağrıyı görmezden gelebilir ve ile başlayan bölüme konsantre olabilirsiniz.((\ @ a $dNum -> ...
İşte $dNum
için sözlük olan Num
kısıtlaması. Oluşturulan kod henüz gerçek türü çözülmediği olduğu bu araçlar a
tü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 Num
türü. Başka bir deyişle, değerlendirilmemiş bir thunk ve şunu elde ediyoruz:
> :sprint intlist
_
Öte yandan, türü olarak belirtin Int
ve 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 .