use shared pipe record for send/recv

The send/recv records have the same fields with the same types, with the exception that send contains writer pipes and recv contains reader pipes. To avoid failures of the compiler to disambiguate based on types, the code now uses a single record type parameterized by the phantom type that distinguishes between a reader and writer pipe.

Depends on #321.