match по вариантным опциям
От: CodingUnit Россия  
Дата: 19.11.11 16:01
Оценка:
Интересно почему для match генерится такой не оптимальный код, например:

  [Record]
  public variant DecisionNode
  {
    | Condition 
      {
        condition : GuardNode;
        body : DecisionNode;
        else_node : DecisionNode;

      }
    | Action
      {
        condition : option[GuardNode];
        body : DecisionNode;
      }
    | Else
      {
        body : DecisionNode;
      }
    | Target 
      {
        target : TransitionTarget;
        destination : TransitionDestination;

      }
  }



public Fold[T](init : T, 
                  cond : T * GuardNode * Condition -> T, 
                  els : T * Else -> T, 
                  targ : T * TransitionTarget * TransitionDestination * Target -> T, 
                  act : T * option[GuardNode] * DecisionNode.Action -> T) : T
    {
      def loop(e, acc, cont)
      {
        match (e)
        {
          | Target(x, d)       as t => cont(targ(acc, x, d, t))
          | Condition(c, b, e) as t => loop(b, acc, bacc => 
                                                    loop(e, bacc, eacc => 
                                                                  cont(cond(eacc, c, t))))

          | Else(b)            as t => loop(b, acc, bacc => cont(els(bacc, t)))
          | Action(c, b)       as t => loop(b, acc, bacc => cont(act(bacc, c, t)))
        }
      }

      loop(this, init, x => x)
    }


здесь обычный перебор веток варианта в match, в рефлекторе он генерит такой код:

       if (!(e is Condition))
        {
            if (!(e is Action))
            {
                if (!(e is Else))
                {
                    if (!(e is Target))
                    {
                        throw new MatchFailureException();
                    }
                    Target t = (Target) e;
                    int x = ((Target) e).target;
                    int d = ((Target) e).destination;
                    return e_._N_cont_4406.apply(_N_xnode_4367(_N_FoldThis_cp_4381._N_targ_4361.apply(x, d, t), null, null, t));
                }

то есть он смотрит оператором is те ли это типы, не проще ли использовать _N_GetVariantCode(), и по нему узнавать что это за экземпляр?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.