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 ()
.
因此,... <&> print
是IO (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
。
所以我写了一个程序来查询外汇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 ()
.
因此,... <&> print
是IO (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
。