mangle :: [TlExpr] -> DebugOr [TlExpr]
mangle = traverse mangleTopLevel
  where
    mangleTopLevel (TlDef x qt@(Unquantified ct) e) =
      TlDef <$> name <*> typ <*> expr
      where
        name = appendTypeSuffix x ct
        typ = return qt
        expr = mangleExpr e
    mangleTopLevel (TlFuncDef x bs ct e) =
      TlFuncDef <$> name <*> bindings <*> retType <*> expr
      where
        arrowT = CTArrow (map snd bs) ct
        name = if x == "main" then return x else appendTypeSuffix x arrowT
        bindings = traverse mangleBinding bs
        retType = return ct
        expr = mangleExpr e
    mangleTopLevel (TlDef _ (Quantified _ _ _) _) =
      fail "mangler found a quantified top-level definition"

-- | Appends a type suffix to a string.
-- I would really like `$` to delimit names from types, but Haskell shorts are
-- messed up.
mangle :: [TlExpr] -> DebugOr [TlExpr]
mangle = traverse mangleTopLevel
  where
    mangleTopLevel (TlDef x qt@(Unquantified ct) e) =
      TlDef <$> name <*> typ <*> expr
      where
        name = appendTypeSuffix x ct
        typ = return qt
        expr = mangleExpr e
    mangleTopLevel (TlFuncDef x bs ct e) =
      TlFuncDef <$> name <*> bindings <*> retType <*> expr
      where
        arrowT = CTArrow (map snd bs) ct
        name = if x == "main" then return x else appendTypeSuffix x arrowT
        bindings = traverse mangleBinding bs
        retType = return ct
        expr = mangleExpr e
    mangleTopLevel (TlDef _ (Quantified _ _ _) _) =
      fail "mangler found a quantified top-level definition"

-- | Appends a type suffix to a string.
-- I would really like `$` to delimit names from types, but Haskell shorts are
-- messed up.
mangle = traverse mangleTopLevel
  where
    mangleTopLevel (TlDef x qt@(Unquantified ct) e) =
      TlDef <$> name <*> typ <*> expr
      where
        name = appendTypeSuffix x ct
        typ = return qt
        expr = mangleExpr e
    mangleTopLevel (TlFuncDef x bs ct e) =
      TlFuncDef <$> name <*> bindings <*> retType <*> expr
      where
        arrowT = CTArrow (map snd bs) ct
        name = if x == "main" then return x else appendTypeSuffix x arrowT
        bindings = traverse mangleBinding bs
        retType = return ct
        expr = mangleExpr e
    mangleTopLevel (TlDef _ (Quantified _ _ _) _) =
      fail "mangler found a quantified top-level definition"

-- | Appends a type suffix to a string.
-- I would really like `$` to delimit names from types, but Haskell shorts are
-- messed up.