为什么我不能用seq强制执行IO操作?

 阿思翠 发布于 2023-02-13 14:36

鉴于此代码段:

someFunction x = print x `seq` 1

main = do print (someFunction "test")

代码执行时为什么不print x打印test

$./seq_test 
1

如果我替换它error我可以检查左操作数seq 是否确实被评估.

我怎样才能达到预期的输出:

test
1

只修改someFunction

1 个回答
  • 评估一个IO动作什么都不做.那就对了!

    如果您愿意,IO类型的值只是"指令列表".因此,所有你与该做的seq是强制程序,以确保1什么应该,如果是真正的动作来完成使用.使用动作与评估无关,它意味着单独将其与main呼叫绑定.但是,正如你所说,因为这someFunction是一个非monadic签名的函数,这在这里不可能发生.

    你可以做什么...... 但不要

    import Foreign
    
    someFunction x = unsafePerformIO (print x) `seq` 1
    

    这实际上将评估与IO执行相结合.这通常在Haskell中是一个非常糟糕的主意,因为评估可能发生在完全不可预测的顺序上,可能发生的次数可能比你想象的要多(因为编译器假设参考透明度),以及其他混乱场景.

    正确的解决方案是将签名更改为monadic:

    someFunction :: Int -> IO Int
    someFunction x = do
         print x
         return 1
    
    main = do
         y <- someFunction "test"
         print y
    

    1事实上,即使没有,程序也尽可能确定seq.只有通过执行操作才能获得更多细节.

    2023-02-13 14:38 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有