В haskell мне нужна глобальная переменная, поэтому я решил использовать слот IORef, вот мой план:
memo :: IORef Int
memo = unsafePerformIO $ newRefInt 9999
evaluate ARGs s = do
v <- Right $ unsafePerformIO $ readIORef memo
val <- Right $ VInt v
return $ (val, s)
evaluate (Call funcID exp) s = do
...
Right $ writeIORef memo 100
...
Мой план заключается в том, что когда исполнитель оценивает узел «Вызов», он сохраняет параметр в слот. Затем, когда оценивается узел «ARGs», этот слот для заметок будет прочитан.
Но что бы я ни делал, я просто могу прочитать 9999, но не могу записать в этот слот новое значение.
Даже я пробовал:
memo :: IORef Int
memo = unsafePerformIO $ newRefInt 9999
evaluate ARGs s = do
Right $ writeIORef memo 100
v <- Right $ unsafePerformIO $ readIORef memo
val <- Right $ VInt v
return $ (val, s)
Все равно получится, что memo = 9999. Почему?
unsafePerformIO
. Если вы обнаружите, что используете его, найдите другой способ сделать это с помощью монадыIO
. Это вызовет больше проблем, чем решит обычный код. Это только там для очень специализированных случаев. - person bheklilr   schedule 05.12.2013unsafePerformIO
был введен только с интерфейсом чужих функций: для выполнения чистых вычислений в чистом коде, где они должны быть, когда компилятор, однако, не может доказать его правильность, потому что вы вызываете функции, написанные на другом языке. (побочный) язык. - person leftaroundabout   schedule 05.12.2013{-# NOINLINE memo #-}
. Без этого компилятор может (почти наверняка будет) встроить ссылки наmemo
, что приведет к тому, что разные части вашего кода будут обращаться к разнымIORef
. - person John L   schedule 05.12.2013