2014-07-25 16 views
6

Haskell'deki tembel değerlendirmeler hakkında bir şeyler okuyorum ve bir sorum var. Örneğin aşağıda belirtilen hesaplamaları vardır:Veri yapılarının tembel değerlendirilmesi

Prelude> let x = 1 + 1 :: Int 
Prelude> let y = (x,x) 

Ve x değerini aldıktan sonra:

Prelude> :sprint x 
x = _ 

Bu unevaluated bu. Tamam, şimdi en y değeri elde edelim: yx and it's unevaluated bağlıdır, çünkü çok unevaluated olan

Prelude> :sprint y 
y = (_,_) 

. Şimdi aynı örneği ancak ::Int olmadan deneyelim:

Prelude> let x = 1 + 1 
Prelude> let y = (x, x) 
Prelude> :sprint y 
y = _ 

Neden y değeri yerine (_, _)_ biz ::Int olmadan çalışırken?

Prelude> let x = 1 + 1 
Prelude> :t x 
x :: Num a => a 
Prelude> let x = 1 + 1 :: Int 
Prelude> :t x 
x :: Int 

Ama neden y değerleri buna bağlıdır:

Onların farklı türleri vardır görüyoruz?

Teşekkür ederiz. neler oluyor

+1

Şimdi gerçekten eğlenceli bir bölüm için, 'x' türüne sahip 'Num a => a', 'x' ve 'y' değerlerini tam olarak değerlendirdikten sonra ne olur? "Sprint" temsillerine ne olur? – bheklilr

+0

@bheklilr, evet, çok ilginç. Ben yaptım: 'x' ve' y' için 'seq', değerleri basar, ancak: sprint baskı' _' – 0xAX

+1

'x' türünü' 'a => a' olduğunda '' değerlendirmek '' için ne anlama gelir? ? Derleyici bununla ne yapacağını nasıl biliyor? '' '' In hangi uygulamasının kullanılacağını bilmediğinde 'x''in değeri '2' olduğunu söyleyebilir? Kendi türlerimi, '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '(MyInt y) = MyInt (x-y)' olarak tanımladıktan sonra uygulayabilirim. '2' değeri var? – bheklilr

cevap

7

Eğer türü Num a => a olması x belirttiğiniz zaman, derleyici muhtemelen 1 + 1 gerçekleştirirken kullanmak Num hangi örneği bilmiyor olabilir. Bunun yerine, varsayılanı kullanmaktır. GHC, belirli tipler için varsayılan türleri tanımlar, böylece hangi beton tipinin kullanılacağını belirlemenin olası bir yolu olmadığında, hataları artırmadan anlamlı sonuçlar verebilir. Yani

> let x :: Num a => a 
|  x = 1 + 1 
> x 
2 
> :sprint x 
x = _ 

görünce GHCi Num için varsayılan türü olarak Integer seçer Bunun nedeni, ancak bu işlemi yaparken bir olmadığından bu x 'ın hafıza konumda sonucu saklamaz Bu doğru cevap bile olup olmadığını bilmenin yolu. Bu nedenle :sprint numaralı telefondan x = _'u görüyorsunuz, aslında x :: Num a => a'u değerlendirmemiş, x :: Integer olarak değerlendiriliyor. Hatta bununla karışıklık kendinizi varsayılan edebilirsiniz:

> newtype MyInt = MyInt Int deriving (Eq) 
> 
> instance Show MyInt where 
|  show (MyInt i) = show i 
> instance Num MyInt where 
|  (MyInt x) + (MyInt y) = MyInt (x - y) 
|  fromInteger = MyInt . fromInteger 
> 
> default (MyInt) 
> x 
0 

Şimdi biz 1 + 1 = 0 söylediniz! Muhtemelen GHC'nin bu işlevselliği için hiç bir zaman kullanamayacağınızı, ancak bunun bilinmesi gerektiğini unutmayın.

+0

büyük bir açıklama +1 ve teşekkürler – Carsten

+0

btw: sistemimde GHCi' x' '' 2 :: Integer' ayarlayacaktır değerlendirdikten sonra! – Carsten

İlgili konular