recursivelyImportExternalExpression :: L2.L2Model -> L2.Identifier -> L2.L2Expression -> ModelTranslation L2.L2Expression
recursivelyImportExternalExpression foreignMod foreignURL targetEx =
  case targetEx of
    L2.L2ExApply ss op arg ->
      L2.L2ExApply ss
        <$> recursivelyImportExternalExpression foreignMod foreignURL op
        <*> recursivelyImportExternalExpression foreignMod foreignURL arg
    L2.L2ExReferenceLabel ss l ->
      L2.L2ExReferenceLabel ss
        <$> recursivelyImportExternalLabel foreignMod foreignURL l
    L2.L2ExReferenceValue ss valueID ->
      L2.L2ExReferenceValue ss
        <$> recursivelyImportExternalValue foreignMod foreignURL valueID
    L2.L2ExReferenceClassValue ss cval ->
      L2.L2ExReferenceClassValue ss
        <$> recursivelyImportExternalClassValue foreignMod foreignURL cval
    L2.L2ExBoundVariable ss svid ->
      L2.L2ExBoundVariable ss
        <$> recursivelyImportExternalScopedValue foreignMod foreignURL svid
    L2.L2ExLiteralReal ss uex rv ->
      L2.L2ExLiteralReal ss
        <$> recursivelyImportExternalUnitExpression foreignMod foreignURL uex
        <*> (return rv)
    L2.L2ExMkProduct ss vals ->
      L2.L2ExMkProduct ss
        <$> mapM (\(lab, ex) ->
                   (,)
                     <$> recursivelyImportExternalLabel foreignMod foreignURL lab
                     <*> recursivelyImportExternalExpression foreignMod foreignURL ex) vals
    L2.L2ExMkUnion ss l ex ->
      L2.L2ExMkUnion ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
                        <*> recursivelyImportExternalExpression foreignMod foreignURL ex
    L2.L2ExUnmkUnion ss l ex ->
      L2.L2ExUnmkUnion ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
                          <*> recursivelyImportExternalExpression foreignMod foreignURL ex
    L2.L2ExIsLabel ss l ex ->
      L2.L2ExIsLabel ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
                        <*> recursivelyImportExternalExpression foreignMod foreignURL ex
    L2.L2ExProject ss l ->
      L2.L2ExProject ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
    L2.L2ExAppend ss l ->
      L2.L2ExAppend ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
    L2.L2ExLambda ss bv val ->
      L2.L2ExLambda ss <$> recursivelyImportExternalScopedValue foreignMod foreignURL bv
                       <*> recursivelyImportExternalExpression foreignMod foreignURL val
    L2.L2ExCase ss expr values ->
      L2.L2ExCase ss <$> recursivelyImportExternalExpression foreignMod foreignURL expr
                     <*> mapM (\(l, ex) ->
                                (,)
                                  <$> recursivelyImportExternalLabel foreignMod foreignURL l
                                  <*> recursivelyImportExternalExpression foreignMod foreignURL ex
                              ) values
    L2.L2ExLet ss expr closureNS closureExprs ->
      L2.L2ExLet ss <$> recursivelyImportExternalExpression foreignMod foreignURL expr
                    <*> recursivelyImportExternalNS foreignMod foreignURL closureNS
                    <*> mapM (recursivelyImportExternalExpression foreignMod foreignURL) closureExprs
    L2.L2ExString ss bs -> pure $ L2.L2ExString ss bs
    L2.L2ExSignature ss ex sig ->
      L2.L2ExSignature ss
        <$> recursivelyImportExternalExpression foreignMod foreignURL ex
        <*> recursivelyImportExternalDomainExpression foreignMod foreignURL sig
recursivelyImportExternalExpression :: L2.L2Model -> L2.Identifier -> L2.L2Expression -> ModelTranslation L2.L2Expression
recursivelyImportExternalExpression foreignMod foreignURL targetEx =
  case targetEx of
    L2.L2ExApply ss op arg ->
      L2.L2ExApply ss
        <$> recursivelyImportExternalExpression foreignMod foreignURL op
        <*> recursivelyImportExternalExpression foreignMod foreignURL arg
    L2.L2ExReferenceLabel ss l ->
      L2.L2ExReferenceLabel ss
        <$> recursivelyImportExternalLabel foreignMod foreignURL l
    L2.L2ExReferenceValue ss valueID ->
      L2.L2ExReferenceValue ss
        <$> recursivelyImportExternalValue foreignMod foreignURL valueID
    L2.L2ExReferenceClassValue ss cval ->
      L2.L2ExReferenceClassValue ss
        <$> recursivelyImportExternalClassValue foreignMod foreignURL cval
    L2.L2ExBoundVariable ss svid ->
      L2.L2ExBoundVariable ss
        <$> recursivelyImportExternalScopedValue foreignMod foreignURL svid
    L2.L2ExLiteralReal ss uex rv ->
      L2.L2ExLiteralReal ss
        <$> recursivelyImportExternalUnitExpression foreignMod foreignURL uex
        <*> (return rv)
    L2.L2ExMkProduct ss vals ->
      L2.L2ExMkProduct ss
        <$> mapM (\(lab, ex) ->
                   (,)
                     <$> recursivelyImportExternalLabel foreignMod foreignURL lab
                     <*> recursivelyImportExternalExpression foreignMod foreignURL ex) vals
    L2.L2ExMkUnion ss l ex ->
      L2.L2ExMkUnion ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
                        <*> recursivelyImportExternalExpression foreignMod foreignURL ex
    L2.L2ExUnmkUnion ss l ex ->
      L2.L2ExUnmkUnion ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
                          <*> recursivelyImportExternalExpression foreignMod foreignURL ex
    L2.L2ExIsLabel ss l ex ->
      L2.L2ExIsLabel ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
                        <*> recursivelyImportExternalExpression foreignMod foreignURL ex
    L2.L2ExProject ss l ->
      L2.L2ExProject ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
    L2.L2ExAppend ss l ->
      L2.L2ExAppend ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
    L2.L2ExLambda ss bv val ->
      L2.L2ExLambda ss <$> recursivelyImportExternalScopedValue foreignMod foreignURL bv
                       <*> recursivelyImportExternalExpression foreignMod foreignURL val
    L2.L2ExCase ss expr values ->
      L2.L2ExCase ss <$> recursivelyImportExternalExpression foreignMod foreignURL expr
                     <*> mapM (\(l, ex) ->
                                (,)
                                  <$> recursivelyImportExternalLabel foreignMod foreignURL l
                                  <*> recursivelyImportExternalExpression foreignMod foreignURL ex
                              ) values
    L2.L2ExLet ss expr closureNS closureExprs ->
      L2.L2ExLet ss <$> recursivelyImportExternalExpression foreignMod foreignURL expr
                    <*> recursivelyImportExternalNS foreignMod foreignURL closureNS
                    <*> mapM (recursivelyImportExternalExpression foreignMod foreignURL) closureExprs
    L2.L2ExString ss bs -> pure $ L2.L2ExString ss bs
    L2.L2ExSignature ss ex sig ->
      L2.L2ExSignature ss
        <$> recursivelyImportExternalExpression foreignMod foreignURL ex
        <*> recursivelyImportExternalDomainExpression foreignMod foreignURL sig
recursivelyImportExternalExpression foreignMod foreignURL targetEx =
  case targetEx of
    L2.L2ExApply ss op arg ->
      L2.L2ExApply ss
        <$> recursivelyImportExternalExpression foreignMod foreignURL op
        <*> recursivelyImportExternalExpression foreignMod foreignURL arg
    L2.L2ExReferenceLabel ss l ->
      L2.L2ExReferenceLabel ss
        <$> recursivelyImportExternalLabel foreignMod foreignURL l
    L2.L2ExReferenceValue ss valueID ->
      L2.L2ExReferenceValue ss
        <$> recursivelyImportExternalValue foreignMod foreignURL valueID
    L2.L2ExReferenceClassValue ss cval ->
      L2.L2ExReferenceClassValue ss
        <$> recursivelyImportExternalClassValue foreignMod foreignURL cval
    L2.L2ExBoundVariable ss svid ->
      L2.L2ExBoundVariable ss
        <$> recursivelyImportExternalScopedValue foreignMod foreignURL svid
    L2.L2ExLiteralReal ss uex rv ->
      L2.L2ExLiteralReal ss
        <$> recursivelyImportExternalUnitExpression foreignMod foreignURL uex
        <*> (return rv)
    L2.L2ExMkProduct ss vals ->
      L2.L2ExMkProduct ss
        <$> mapM (\(lab, ex) ->
                   (,)
                     <$> recursivelyImportExternalLabel foreignMod foreignURL lab
                     <*> recursivelyImportExternalExpression foreignMod foreignURL ex) vals
    L2.L2ExMkUnion ss l ex ->
      L2.L2ExMkUnion ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
                        <*> recursivelyImportExternalExpression foreignMod foreignURL ex
    L2.L2ExUnmkUnion ss l ex ->
      L2.L2ExUnmkUnion ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
                          <*> recursivelyImportExternalExpression foreignMod foreignURL ex
    L2.L2ExIsLabel ss l ex ->
      L2.L2ExIsLabel ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
                        <*> recursivelyImportExternalExpression foreignMod foreignURL ex
    L2.L2ExProject ss l ->
      L2.L2ExProject ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
    L2.L2ExAppend ss l ->
      L2.L2ExAppend ss <$> recursivelyImportExternalLabel foreignMod foreignURL l
    L2.L2ExLambda ss bv val ->
      L2.L2ExLambda ss <$> recursivelyImportExternalScopedValue foreignMod foreignURL bv
                       <*> recursivelyImportExternalExpression foreignMod foreignURL val
    L2.L2ExCase ss expr values ->
      L2.L2ExCase ss <$> recursivelyImportExternalExpression foreignMod foreignURL expr
                     <*> mapM (\(l, ex) ->
                                (,)
                                  <$> recursivelyImportExternalLabel foreignMod foreignURL l
                                  <*> recursivelyImportExternalExpression foreignMod foreignURL ex
                              ) values
    L2.L2ExLet ss expr closureNS closureExprs ->
      L2.L2ExLet ss <$> recursivelyImportExternalExpression foreignMod foreignURL expr
                    <*> recursivelyImportExternalNS foreignMod foreignURL closureNS
                    <*> mapM (recursivelyImportExternalExpression foreignMod foreignURL) closureExprs
    L2.L2ExString ss bs -> pure $ L2.L2ExString ss bs
    L2.L2ExSignature ss ex sig ->
      L2.L2ExSignature ss
        <$> recursivelyImportExternalExpression foreignMod foreignURL ex
        <*> recursivelyImportExternalDomainExpression foreignMod foreignURL sig