content: {-# LANGUAGE BangPatterns #-}
  {-# LANGUAGE BlockArguments #-}
  {-# LANGUAGE MagicHash #-}
  {-# LANGUAGE StandaloneKindSignatures #-}
  {-# LANGUAGE UnboxedTuples #-}
  {-# LANGUAGE UnliftedDatatypes #-}
  
  module Main where
  
  import Data.Kind
  import System.Mem (performGC)
  import GHC.Exts
  import GHC.IO
  
  type U :: UnliftedType
  data U = U Int#
  
  main :: IO ()
  main = do
    res <- IO \ s0 ->
      case newMVar# s0 of
        (# s1, mvar #) ->
          case newMutVar# False s1 of
            (# s2, val_var #) ->
              case keepAlive# val_var s2 (inner mvar val_var) of
                (# s3, Res wk strs #) ->
                  case unIO performGC s3 of
                    (# s4, _ #) ->
                      case deRefWeak# wk s4 of
                        (# s5, j, _ #) ->
                          case takeMVar# mvar s5 of
                            (# s6, r #) ->
                              (# s6, strs ++ [ show (I# j), r ] #)
    print res
  
  data Res = Res (Weak# (MutableByteArray# RealWorld)) [String]
  
  inner :: MVar# RealWorld String
        -> MutVar# RealWorld Bool
        -> State# RealWorld
        -> (# State# RealWorld, Res #)
  inner mvar u s0 =
    case newByteArray# 42# s0 of
      (# s1, ba# #) ->
        case mkWeak# u ba# (finalise mvar) s1 of
          (# s2, wk #) ->
            case deRefWeak# wk s2 of
              (# s3, i, ba'# #) -> (# s3, Res wk [ show (I# i), show (I# (sizeofMutableByteArray# ba'#)) ] #)
  
  finalise :: MVar# RealWorld String -> State# RealWorld -> (# State# RealWorld, () #)
  finalise mvar s0 =
    case putMVar# mvar "finalised!" s0 of
      s1 -> (# s1, () #)
  