假设你在haskell中有一个nullary函数,它在代码中多次使用.它总是只评估一次吗?我已经测试了以下代码:
sayHello :: Int
sayHello = unsafePerformIO $ do
putStr "Hello"
return 42
test :: Int -> [Int]
test 0 = []
test n = (sayHello:(test (n-1)))
Run Code Online (Sandbox Code Playgroud)
当我调用测试10时,它会将"Hello"写入一次,因此它表示在第一次评估后存储了函数的结果.我的问题是,它有保证吗?我会在不同的编译器中得到相同的结果吗?
编辑 我使用unsafePerformIO的原因是检查sayHello是否被多次评估.我不在我的程序中使用它.通常我希望sayHello每次评估都会得到完全相同的结果.但这是一个耗时的操作,所以我想知道它是否可以通过这种方式访问,或者是否应该作为参数传递,以确保它不被多次评估,即:
test _ 0 = []
test s n = (s:(test (n-1)))
...
test sayHello 10
Run Code Online (Sandbox Code Playgroud)
根据答案,应该使用它.
我在Visual Studio 2012中有dll项目,它是用/ MT(静态多线程运行时库)编译的.它还链接第三方静态库,也用/ MT(库A)编译,到目前为止没问题.
问题来自于另一个静态库(库B),它不幸地用/ MD编译.在我的dll中,我需要链接两者,除了它们之外别无选择(我不能用不同的选项重新编译它们).我能够成功地将所有内容链接在一起,但现在我遇到内存分配和删除问题 - 有时它无法删除已分配的对象,有时会发生另一个奇怪的错误.我相信它是由混合内存管理函数引起的,我的dll的不同部分使用 - 当调用new时,对象在库B中创建,但是当调用delete时,它尝试使用不同的函数集释放内存 - 但是我可能是错的.
所以我的问题是,这真的是由混合内存管理功能引起的吗?如果是这样,有没有办法让这项工作在一起?
我想到的唯一解决方案是将库B包装在用/ MD编译的另一个dll中,然后从原始dll使用它以确保将使用不同的内存管理功能.我不确定,如果这会有所帮助,我想避免它.