为什么这个Haskell程序有所不同?

sin*_*law 23 haskell

看起来像[1,2,3]和[1..3]之间的奇怪区别.

在下面使用runghc打印出一个"True",然后永久挂起:为什么?(我正在使用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!
Run Code Online (Sandbox Code Playgroud)

注意,上面对DiffTime的二进制实现是错误的; 但这不是重点.

sin*_*law 33

感谢#haskell的otulp,原因如下:

Prelude> take 3 [1..2] :: [Data.Time.DiffTime]
[1s,1.000000000001s,1.000000000002s]
Run Code Online (Sandbox Code Playgroud)

这是因为Enum实例的原因DiffTime

更改elipsis为此问题可解决此问题:

elipsis = map fromIntegral ([1..10] :: [Int])
Run Code Online (Sandbox Code Playgroud)

  • 那个 `Enum` 实例本身非常晦涩。 (2认同)