Haskell mapM_ 不打印

Haskell mapM_ does not print

所以我写了一个程序来查询外汇API(外汇),它就像一个魅力,但是当我想查询每个可用的货币对时,它评估所有API调用,因为它需要很长时间才能执行但不打印任何内容。

import Data.Functor ((<&>))

supportedPairs :: IO (Maybe [(String, String)])
forex :: String -> String -> IO (Maybe (Scientific, UnixTime))


main :: IO ()
main = do
    x <- supportedPairs
    mapM_ (flip (<&>) print . uncurry forex) (fromJust x)
    -- this prints nothing at all

单次调用就像这样工作得很好:

main = do
    x <- supportedPairs    
    u <- (uncurry forex . (flip (!!) 10 . fromJust)) x
    print u
    -- this prints "Just (438.685041,UnixTime {utSeconds = 1649588583, utMicroSeconds = 0})"

为什么 mapM_ 不打印结果,尽管它们已被评估?如果我正确理解了 Haskell 的惰性,那么如果不打印结果,那么一开始就不应该对其进行评估?

检查类型:

print... -> IO ().

因此,... <&> printIO (IO ())。注意这里的双IO。

因此,对其进行映射,运行 将是“最外层的 IO”而不是“最内层的 IO”。更具体地说,比较一下:

main = do
  x <- print True >> return 5          -- x is 5
  y <- return (print True >> return 5) -- y is an IO action
  ...

这里只执行第一个print True:第二个IO动作用来定义y,但是直到我们运行 y它才会被执行。

最后一点:在这里,您不需要 <&>,因为它会创建嵌套的 IO。使用 flip (>>=) print(或 (=<<) print,或 (>>= print))而不是 flip <&> print