Как передать параметры RTS в runghc?

Для ghci, я могу ограничить память, которую ghci может использовать

$ ghci +RTS -M10m -RTS

Когда я компилирую всю программу, я могу

$ ghc -rtsopts a.hs 

затем

$ ./a +RTS -M10m

Как это сделать для runghc a.hs? Я пробовал несколько способов, например runghc a.hs +RTS -M10m, но ни один из них не работает. Единственный вариант, который я мог ограничить память, -

$ export GHCRTS='-M10m'
$ runghc a.hs

но я хочу, чтобы это было только один раз, поэтому я предпочитаю делать это, передавая аргументы runghc.


Изменить: я проверяю, работает ли эта опция или нет, используя следующую стратегию (только потому, что я не знаю лучших способов):

-- a.hs
f x = f (f x)
main = print $ seq (f 0) 0

Откройте два терминала, один для команды top и другой для выполнения кода. Если выполнение перестает говорить "Heap исчерпано", я делаю вывод, что -M[number]m работает. Если выполнение продолжается и использует огромный объем памяти, я убиваю процесс и делаю вывод, что это не удалось.

Ответ 1

Использование GHCRTS=... runghc ... в качестве chi говорит, что это единственный способ. Из-за того, как runghc интерпретирует свою командную строку, +RTS интерпретируется как параметры RTS для самого runghc (если это в конце) или как имя программы (если оно в начале). Он никогда не достигает времени выполнения. Вы можете принудительно передать его в программу с помощью --RTS +RTS ..., но затем он рассматривается как аргумент программы и до сих пор не отображается средой выполнения.

Чтобы исследовать это, я написал оболочку оболочки script для ghc, которая отслеживает ее аргументы и передает это значение в runghc с опцией -f.

Создайте файл ghc-wrapper, содержащий:

#!/bin/sh -x
exec ghc "[email protected]"

Опция -x сообщает /bin/sh проследить каждую строку. Используйте это с помощью runghc:

$ runghc -f ./ghc-wrapper Hello.hs
+ exec ghc -ignore-dot-ghci -x hs -e :set prog "Hello.hs" -e :main [] Hello.hs
Hello, World!

$ runghc -f ./ghc-wrapper Hello.hs +RTS -s
+ exec ghc -ignore-dot-ghci -x hs -e :set prog "Hello.hs" -e :main [] Hello.hs
Hello, World!
    114,016 bytes allocated in the heap # runghc heap, not Hello's
    ...

$ runghc -f ./ghc-wrapper Hello.hs --RTS +RTS -s
+ exec ghc -ignore-dot-ghci -x hs -e :set prog "Hello.hs" -e :main ["+RTS","-s"] Hello.hs
Hello, World!

$ runghc -f ./ghc-wrapper -- +RTS -s -RTS Hello.hs
+ exec ghc -ignore-dot-ghci -e :set prog "+RTS" -e :main ["-s","-RTS","Hello.hs"] +RTS
+RTS:1:55:
    Not in scope: `main'
    Perhaps you meant `min' (imported from Prelude)

Нам действительно нужно выполнить runghc:

$ ghc -ignore-dot-ghci -x hs +RTS -s -RTS -e ':set prog "Hello.hs"' -e ':main []' Hello.hs
Hello, World!
      80,654,256 bytes allocated in the heap
      ...

Но нет способа указать это, потому что runghc не относится к +RTS специально.