Будет ли использование Scala более функциональным способом (scalaz) снижает производительность / ремонтопригодность?

В настоящее время я работаю над небольшим проектом (<10k loc), который в основном чистый, но полагается на изменяемые оптимизации, в основном основанные на итераторах и повторном использовании некоторых структур данных для сложных вычислений.

Я бы хотел немного изучить функциональное программирование и повысить безопасность типов, например, обертывание изменяемых вычислений в монады преобразователей состояний и т.п. Для этой цели существует библиотека scalaz.

Вопрос первый

При абстрагировании моих вычислений в более крупном масштабе с использованием всех причудливых функциональных вещей, я введу убийцы производительности, от которых я не избавлюсь? Например, когда мои вычисления по колено в монадах?

Вопрос второй

Возможно ли это вообще с учетом ограниченного вывода типов в Scala? В настоящее время я борюсь с очень большими подписями типа (возможно, потому, что я не знаю, как правильно от них избавиться). Я полагаю, что переход к более «функциональному» приведет к появлению еще большего количества такого шаблонного кода.

Заявление об ограничении ответственности

Я не сомневаюсь, хорош или плох функциональный подход. Задавать этот вопрос для Haskell бессмысленно. Я сомневаюсь, имеет ли смысл делать это для Scala.

Редактировать по запросу: пример сигнатур большого типа в моем проекте

(но это был бы другой вопрос)

Следующий код описывает итеративное вычисление на объект ввода с параметризацией типа ( DiscreteFactorGraph [VariableType, FactorType [VariableType]] ). Вы можете создать объект вычисления с помощью createInitialState и выполнить вычисления с помощью advanceState и, наконец, извлечь из него некоторую информацию с помощью маргиналов .

Мне нужен тип объекта факторного графа (и его типы параметров) должны быть сохранены во время вычислений, чтобы окончательное применение маргиналов давало правильный тип DiscreteMarginals [VariableType] . Я думаю, что в настоящее время мне нужно сохранить только тип переменной внутри типа вычисления (которым является TState ), поэтому перенос типа фактора не используется. Но в другом месте мне нужен даже тип DiscreteFactorGraph , чтобы быть переменным, поэтому мне, как правило, потребуется больше информации о типе, передаваемой через вычисления в будущем.

Я много возился с этой частью и я надеюсь, что есть лучшее решение. В настоящее время у меня есть довольно функциональный подход, в котором есть только эти три функции. Но я должен связать тип через них. В качестве альтернативы я могу определить его как класс и параметризовать класс всеми этими типами, поэтому мне не нужно повторять параметры типа для каждого метода.

object FloodingBeliefPropagationStepper extends SteppingGraphInferer {
  def marginals[V <: DiscreteVariable, F <: DiscreteFactor[V]](state: FloodingBeliefPropagationStepper.TState[V,F]): DiscreteMarginals[V] =
    BeliefPropagation.marginals(state._1, state._2)

  def advanceState[V <: DiscreteVariable, F <: DiscreteFactor[V]](state: FloodingBeliefPropagationStepper.TState[V,F]): FloodingBeliefPropagationStepper.TState[V,F] = {
    val graph = state._1
    (graph,
      BeliefPropagation.computeFactorMessages(
      graph,
      BeliefPropagation.computeVariableMessages(graph, state._2, graph.variables),
      graph.factors))
  }

  def createInitialState[V <: DiscreteVariable, F <: DiscreteFactor[V]](graph: DiscreteFactorGraph[V, F],
                                                                        query: Set[V],
                                                                        random: Random): FloodingBeliefPropagationStepper.TState[V,F] = {
    (graph,
      BeliefPropagation.computeFactorMessages(
      graph,
      BeliefPropagation.createInitialVariableMessages(graph, random),
      graph.factors))
  }

  type TState[V <: DiscreteVariable, F <: DiscreteFactor[V]] = (DiscreteFactorGraph[V,F],Map[(F,V),DiscreteMessage])
}
16
задан ziggystar 17 August 2011 в 09:55
поделиться