module DefImpl { 
 
  import { /Std/IO; /Std/Fmt; } 
 
  // Define an interface for speaker 
 
  interface Speaker { 
    speak(); 
  } 
 
  // Create an implementation for quiet speakers 
 
  struct QuietSpeaker { 
    name: string; 
  } 
 
  impl Speaker { 
    speak(this : QuietSpeaker) { 
      print(this.name); 
      println(" says nothing"); 
    } 
  } 
 
  // Create an implementation for loud speakers 
 
  struct LoudSpeaker { 
    name: string; 
    sound: string; 
  } 
 
  impl Speaker { 
    speak(this : LoudSpeaker) { 
      print(this.name); 
      println(" says "); 
      println(this.sound); 
      println("!"); 
    } 
  } 
 
  // Define some types that will implement speaker 
 
  struct Cat { name : string; }   
  struct Dog { name : string; } 
  struct Wolf { } 
 
  impl Speaker { 
 
    // Cat is a quiet speaker 
    constructor(this : Cat) : QuietSpeaker => { 
      return QuietSpeaker(this.name); 
    } 
 
    // Dog is a loud speaker 
    constructor(this : Dog) : LoudSpeaker => { 
      return LoudSpeaker(this.name, "woof"); 
    } 
 
    // Wolf is a loud speaker 
    constructor(this : Wolf) : LoudSpeaker => { 
      return LoudSpeaker("wolf", "awooo"); 
    } 
  } 
 
  fn test() { 
    const cat = Cat("paws")::Speaker; 
    cat.speak(); 
 
    const dog = Dog("abby")::Speaker; 
    dog.speak(); 
 
    const wolf = Wolf::Speaker; 
    wolf.speak(); 
  } 
}