2014-12-11 18 views
23

Wygląda dziwną różnicę między [1,2,3] a [1..3].Dlaczego ten program Haskella różni się?

Użycie polecenia runghc na poniższym rysunku powoduje wypisanie jednego "True", a następnie zawiesza się na zawsze: dlaczego? (Używam GHC 7.8.3)

module Main where 

import Data.Functor((<$>)) 
import Data.Time.Clock(DiffTime) 
import Data.Binary(Binary(..), encode, decode, Get) 
import Data.Int(Int64) 

instance Binary DiffTime where 
    put x = put (truncate (x * 10^12) :: Int64) 
    get = ((/ 10^12) . fromIntegral) <$> (get :: Get Int64) 

prop_getput_difftime :: DiffTime -> Bool 
prop_getput_difftime x = x == ((decode . encode $ x) :: DiffTime) 

explicit :: [DiffTime] 
explicit = [1,2,3,4,5,6,7,8,9,10] 

elipsis :: [DiffTime] 
elipsis = [1..10] 

main :: IO() 
main = do 
    print $ all prop_getput_difftime explicit 
    print $ all prop_getput_difftime elipsis -- diverges! 

Uwaga powyższa implementacja binarny dla difftime jest źle; ale to nie ma znaczenia.

+0

Co się dzieje, jeśli zamieniasz wyciągi? – rightfold

Odpowiedz

33

Dzięki otulp z #haskell, oto powód:

Prelude> take 3 [1..2] :: [Data.Time.DiffTime] 
[1s,1.000000000001s,1.000000000002s] 

co zdarza się z powodu wystąpienia Enum dla DiffTime

Zmiana elipsis na to rozwiązuje problem:

elipsis = map fromIntegral ([1..10] :: [Int]) 
+7

'[1,2..10]' powinno również wystarczyć. –

+0

@PeterWortmann, nice! Jednak dla przyszłej ochrony przed nieświadomymi opiekunami rozwiązanie to jest nieco bardziej niejasne. – sinelaw

+1

Ta sama instancja 'Enum' jest niezrozumiała. – leftaroundabout

Powiązane problemy