Haskell - 无法将类型[]与IO匹配

Mat*_*jKr 4 haskell types program-entry-point quicksort match

我是Haskell的新人.为什么我收到错误消息

(无法在下面的代码中将类型'[]'与'IO' - Haskell匹配.

在主要方面,我只需要运行算法的时间而没有结果.

只想测量算法时间.

qsort1 :: Ord a => [a] -> [a]
qsort1 []     = []
qsort1 (p:xs) = qsort1 lesser ++ [p] ++ qsort1 greater
    where
        lesser  = [ y | y <- xs, y < p ]
        greater = [ y | y <- xs, y >= p ]

main = do
    start <- getCurrentTime
    qsort1 (take 1000000 $ randomRs (1, 100000) (mkStdGen 42))
    end <- getCurrentTime
    print (diffUTCTime end start) 
Run Code Online (Sandbox Code Playgroud)

Sib*_*ibi 6

你的main功能不对.除非qsort1是一个IO动作,否则你无法在IO monad中执行它.相反,你可以把它放在let绑定中:

main = do
    start <- getCurrentTime
    let x = qsort1 (take 1000000 $ randomRs ((1 :: Int), 100000) (mkStdGen 42))
    end <- getCurrentTime
    print (diffUTCTime end start) 
Run Code Online (Sandbox Code Playgroud)

另请注意,我已明确指定了类型注释,1以避免一些编译错误.

但话虽如此,由于懒惰的评估,你实际上无法找到进行排序所需的总时间.x将永远不会被计算,因为它从未在程序中使用过.如果你运行main,它会给你这个绝对错误的输出:

?> main
0.000001s
Run Code Online (Sandbox Code Playgroud)

相反,您可以使用它来计算计算:

main = do
    start <- getCurrentTime
    let x = qsort1 (take 1000000 $ randomRs ((1 :: Int), 100000) (mkStdGen 42))
    print x
    end <- getCurrentTime
    print (diffUTCTime end start)  
Run Code Online (Sandbox Code Playgroud)

您也可以使用BangPatterns扩展来强制计算qsort1:而不是打印:

main = do
    start <- getCurrentTime
    let !x = qsort1 (take 1000000 $ randomRs ((1 :: Int), 100000) (mkStdGen 42))
    end <- getCurrentTime
    print (diffUTCTime end start)   
Run Code Online (Sandbox Code Playgroud)

BangPatterns不会像@kosmikus指出的那样导致全面评估.而是使用criterion专门为benchnmarking制作的库.

  • 爆炸模式在这里不正确.它不会强制进行全面评估,也不会导致正确的结果.只需使用类似标准的基准测试,而不是尝试重新发明轮子. (2认同)
  • 因为爆炸模式一般不会引起全面评估,而只能评估弱头正常形态.并且qsort1返回一个列表. (2认同)