Haskell mapm_不打印

发布于 2025-01-20 16:53:39 字数 838 浏览 3 评论 0原文

因此,我编写了一个程序来查询外汇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的懒惰,那么如果不打印结果,则不应首先对其进行评估?

So I wrote a program to query a forex API (foreign exchange), and it works like a charm, but when I want to query every currency pair available, it evaluates all API calls as it takes a long time to execute but prints nothing.

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

The single calls work just fine like this:

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

Why doesn't the mapM_ print the results although they are evaluated? If I understood Haskell's laziness correctly, then if the results are not to be printed they should not be evaluated in the first place?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

世界如花海般美丽 2025-01-27 16:53:39

检查类型:

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 <&>打印

Check the types:

print is ... -> IO ().

Therefore, ... <&> print is IO (IO ()). Note the double IO here.

Hence, mapping over that, will run the "outermost IO" but not the "innermost IO". More concretely, compare this:

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

Only the first print True here is executed: the second IO action is used to define y but until we run y it won't be executed.

The final point: here, you do not need <&> since that creates the nested IO's. Use flip (>>=) print (or (=<<) print, or (>>= print)) instead of flip <&> print.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文