Ответ 1
Очевидно, что lazyShow
не может иметь тип, который вы укажете. Если строка должна зависеть от текущего состояния оценки, тогда IO String
в результате - лучшее, на что вы можете надеяться.
Если все, что вас интересует, использует это для отладки, то я думаю, что пакет ghc-heap-view (и, возможно, графический интерфейс, такой как ghc-vis) полезны для этой цели. Он определяет команду GHCi :printHeap
, которая может использоваться для отображения описания того, как значение выглядит в куче GHC. Это, возможно, немного более низкоуровневое, чем то, что вы намеревались, но может быть очень полезно лучше понять, как работают ленивые оценки и совместная работа:
Prelude> let nats = [0..]
Prelude> :printHeap nats
(_bco (D:Enum _fun _fun _fun _fun _fun _fun _fun _fun) _fun)()
Prelude> null nats
False
Prelude> System.Mem.performGC
Prelude> :printHeap nats
let x1 = S# 0
in x1 : _thunk x1 (S# 1)
Prelude> nats !! 5
5
Prelude> System.Mem.performGC
Prelude> :printHeap nats
let x1 = S# 5
in S# 0 : S# 1 : S# 2 : S# 3 : S# 4 : x1 : _thunk x1 (S# 1)
Я явно вызываю сборщик мусора через System.Mem.performGC
(как рекомендовано в документации по ghc-heap-view), чтобы немного очистить представление.