In particular, the analogue of XMonad.workspaces is
workspaces', and you can use onCurrentScreen to convert functions
of virtual workspaces to functions of physical workspaces, which work
by marshalling the virtual workspace name and the currently focused
screen into a physical workspace name.

A complete example abusing many of the functions below is available in the
XMonad.Config.Dmwit module.

This turns a naive pretty-printer into one that is aware of the
independent screens. That is, you can write your pretty printer to behave
the way you want on virtual workspaces; this function will convert that
pretty-printer into one that first filters out physical workspaces on other
screens, then converts all the physical workspaces on this screen to their
virtual names.

For example, if you have handles hLeft and hRight for bars on the left and right screens, respectively, and pp is a pretty-printer function that takes a handle, you could write

Take a pretty-printer and turn it into one that only runs when the current
workspace is one associated with the given screen. The way this works is a
bit hacky, so beware: the ppOutput field of the input will not be invoked
if either of the following conditions is met:

Converting between virtual and physical workspaces

You shouldn't need to use the functions below very much. They are used
internally. However, in some cases, they may be useful, and so are exported
just in case. In general, the "marshall" functions convert the convenient
form (like "web") you would like to use in your configuration file to the
inconvenient form (like "2_web") that xmonad uses internally. Similarly,
the "unmarshall" functions convert in the other direction.

If vSort is a function that sorts WindowSpaces with virtual names, then marshallSort s vSort is a function which sorts WindowSpaces with physical names in an analogous way -- but keeps only the spaces on screen s.