2015-09-02 19 views
8

Haskell'i yeni öğrenmeye başladım ve garip bir şey buldum.Haskell'de aralıkları kullanırken harita neden ek bir öğe döndürüyor?

ghci> [0,2..5] 
[0,2,4] 

Bu 3 unsur vardır:

Let bir liste var. Bu liste ile map kullandığınızda ben örneğin, çıktı olarak 3 elementi olsun:

ghci> map (+ 1) [0,2..5] 
[1,3,5] 
ghci> map (* 2) [0,2..5] 
[0,4,8] 
ghci> map (`div` 2) [0,2..5] 
[0,1,2] 

Ama fraksiyonel bölünme kullandığımda çıkış listesinde 4 öğelerini almak:

ghci> map (/ 2) [0,2..5] 
[0.0,1.0,2.0,3.0] 
ghci> length (map (/ 2) [0,2..5]) 
4 

nedenini açıklayabilir misiniz map daha fazla elementi döndürebilir mi?

Teşekkür ederiz!

+1

İlgili: http://stackoverflow.com/q/7290438/2541573 – Jubobs

+1

Not: 'length (map f xs) == uzunluk (map f 'xs')' her uzunluk xs == uzunluk xs 'için . Bu *, * türünden türediği için "map" uygulamasının bağımsız olarak doğru olması gerekir. 'map' farklı tipler arasında ayrım yapamaz ve dolayısıyla kaç elemanın geri döneceğine karar vermiştir. – Bakuriu

cevap

11

O Float ve Double için Enum uygulanması nedeniyle olduğunu: Bunu yapmıyor map var

> [0,2..5] :: [Float] 
[0.0,2.0,4.0,6.0] 

ama Float. Özellikle, enumFromThenTo 0 2 5 :: [Float] numaralı telefonu ararsanız, aynı listeyi alırsınız. Double için aynı sonuçları göreceksiniz.

Bu, the haskell report numaralı makalede belirtilmiştir, ancak davranış kesinlikle açık değildir. Esasen, bu Enum Float örneği tarafından kullanılan numericEnumFromThenTo uygulanması (burada bazı Haskell iç yapıları içine alıyoruz), aşağı gelir: listesini [0.0,2.0,4.0,6.0,8.0,...] üreten

numericEnumFromThenTo n n' m = takeWhile p (numericEnumFromThen n n') 
    where 
     p | n' >= n = (<= m + (n' - n)/2) 
      | otherwise = (>= m + (n' - n)/2) 

numericEnumFromThen n m = iterate (+ (m - n)) n 

Yani var numericEnumFromThen 0.0 2.0, o zaman takeWhile p yapmak Bu durumda, \x -> x <= 5.0 + (2.0 - 0.0)/2 veya daha basit olarak \x -> x <= 6.0 işlevine eşdeğer olan, 6.0'un neden [0.0,2.0..5.0] çıktı listesine dahil edildiğini.

ben açıklayamam bu şekilde uygulanacağı ve, bu çok bana oldukça Şaşırtıcı gelebilir, ama umarım ben bunun uygulanması için nasıl Yanıtım neden .

+5

Niçin önemlidir ki [0,0.1..1] 'her zaman onbir elemente sahiptir, oysaki kaç elementin önemi yoktur [0,2..5]' ilk saçmalıktan beri saçmadır yer. –

+2

@ReidBarton üzerinde ayrıntılı çalışma yapmak için, kayan nokta aralıklarının uygulanması, başlangıç ​​ve bitiş noktası arasındaki farkın * yaklaşık olarak * bir kaç adım olduğu durumlarda, ortak durumda yuvarlama hataları için uzunluğa duyarsız olacak şekilde tasarlanmıştır. Kesiklik yerine yarım adım fazlalığı olmayan olası "karşıt" duruma getirilir. –

İlgili konular