Personally I'd try to use the type system, if possible.
data Box a = Box [a]
data Parcel a = Parcel [a]
data Can = Can
data Truck a = Truck {
tname :: String,
truckContents :: [a]
}
oneboxoftwocanstruck :: Truck (Box Can)
oneboxoftwocanstruck = Truck "Truck of Boxes of Cans" [Box [Can,Can]]
onecantruck :: Truck Can
onecantruck = Truck "Truck of Cans" [Can]
This gets some of the type safety without bogging you down too much. You can still end up with parcels with trucks in them, but it's not too bad. At least cans are just cans, and functions can be written for trucks that only work on trucks, for example.