#line 82 "/home/travis/build/felix-lang/felix/src/packages/core_type_constructors.fdoc"
  
  // Note: some felix internals expect this to be defined here, not in a class, and
  // in this order.  Don't mess with it!
  publish "option type"
  union opt[T] =
    | None
    | Some of T
  ;
  
  open class Option {
  
    instance[T with Show[T]] Str[opt[T]] {
      fun str (x:opt[T]) =>
        match x with
        | Some x => "Some " + (str x)
        | #None => "None"
        endmatch
      ;
    }
  
    // Return the value of the option if it has any, otherwise
    // returns the default value provided
    fun or_else[T] (x:opt[T]) (d:T) : T =>
       match x with
       | Some v => v
       | #None => d
       endmatch
       ;
  
    // Returns the first option if it has the value, otherwise
    // the second option
    fun or_else[T] (x:opt[T]) (alt:opt[T]) : opt[T] =>
       match x with
       | Some _ => x
       | #None => alt
       endmatch
       ;
  
    // If the option has a value, call the given procedure on it
    proc iter[T] (_f:T->void) (x:opt[T]) =>
      match x with
      | #None => {}
      | Some v => { _f v; }
      endmatch
      ;
  
    // Convert an option to a list with either zero or one elements
    ctor[T] list[T] (x:opt[T]) =>
      match x with
      | #None => list[T]()
      | Some v => list[T](v)
      endmatch
    ;
  
    // True if this option has no value
    pure fun is_empty[T] : opt[T] -> 2 =
      | #None => true
      | _ => false
    ;
  
    // True if this option has a value
    pure fun is_defined[T] : opt[T] -> 2 =
      | #None => false
      | _ => true
    ;
  
    // Get the optional value; aborts if no value is available
    fun get[T] : opt[T] -> T =
      | Some v => v
    ;
  
    // If the option has a value, apply the function to it and return a new Some value.
    // If the option has no value, returns None
    fun map[T,U] (_f:T->U) (x:opt[T]): opt[U] =>
      match x with
      | #None => None[U]
      | Some v => Some(_f v)
      endmatch
    ;
  
    // Mimics the filter operation on a list.
    // If there is a value and the predicate returns false for that value, return
    // None.  Otherwise return the same option object.
    fun filter[T] (P:T -> bool) (x:opt[T]) : opt[T] =>
      match x with
      | Some v => if P(v) then x else None[T] endif
      | #None => x
      endmatch
    ;
  
    // Make option types iterable.  Iteration will loop once
    // if there is a value.  It's a handy shortcut for using
    // the value if you don't care about the None case.
    gen iterator[T] (var x:opt[T]) () = {
      yield x;
      return None[T];
    }
  }
  
  class DefaultValue[T] {
    virtual fun default[T]: 1->T;
  
    fun or_default[T]  (x:opt[T]) () =>
                 x.or_else #default[T]
         ;
  
  }