Constrained genericity or bounded quantification means
that a parametrized type or function (see parametric polymorphism)
can only be instantiated on types fulfilling some conditions,
even if those conditions are not used in that function.

Say a type is called "eatable" if you can call the function eat on it.
Write a generic type FoodBox which contains a collection of objects of
a type given as parameter, but can only be instantiated on eatable types.
The FoodBox shall not use the function eat in any way (i.e. without the explicit restriction, it could be instantiated on any type).
The specification of a type being eatable should be as generic as possible
in your language (i.e. the restrictions on the implementation of eatable types
should be as minimal as possible).
Also explain the restrictions, if any, on the implementation of eatable types,
and show at least one example of an eatable type.

 
// This declares the "Eatable" constraint. It could contain no function.
trait Eatable {
    fn eat();
}
 
// This declares the generic "FoodBox" type,
// whose parameter must satisfy the "Eatable" constraint.
// The objects of this type contain a vector of eatable objects.
struct FoodBox<T: Eatable> {
    _data: Vec<T>,
}
 
// This implements the functions associated with the "FoodBox" type.
// This statement is not required, but here it is used
// to declare a handy "new" constructor.
impl<T: Eatable> FoodBox<T> {
    fn new() -> FoodBox<T> {
        FoodBox::<T> { _data: Vec::<T>::new() }
    }
}
 
// This declares a simple type.
struct Banana {}
 
// This makes the "Banana" type satisfy the "Eatable" constraint.
// For that, every declaration inside the declaration of "Eatable"
// must be implemented here.
impl Eatable for Banana {
    fn eat() {}
}
 
// This makes also the primitive "char" type satisfy the "Eatable" constraint.
impl Eatable for char {
    fn eat() {}
}
 
fn main() {
    // This instantiate a "FoodBox" parameterized by the "Banana" type.
    // It is allowed as "Banana" implements "Eatable".
    let _fb1 = FoodBox::<Banana>::new();
 
    // This instantiate a "FoodBox" parameterized by the "char" type.
    // It is allowed, as "char" implements "Eatable".
    let _fb2 = FoodBox::<char>::new();
 
    // This instantiate a "FoodBox" parameterized by the "bool" type.
    // It is NOT allowed, as "bool" does not implement "Eatable".
    //let _fb3 = FoodBox::<bool>::new();
}
 