Монадическая редукция в государственной монаде

Я застрял, пытаясь сократить список внутри монады состояний, используя функцию, возвращающую State:

def op(t1: T, t2: T): State[S, T] 
val list: State[S, List[T]]

I'd like to reduce the list to get a State[S, T]


person Magnus Eklund    schedule 19.12.2015    source источник


Ответы (1)


Невозможно выполнить эту операцию безопасно, как написано (что произойдет, если список пуст?), Но если у вас есть элемент идентификации для op, вы можете использовать foldLeftM из Foldable:

list.flatMap(_.foldLeftM[({ type L[x] = State[S, x] })#L, T](opId)(op))

В качестве альтернативы вы можете написать что-то вроде этого:

list.flatMap {
  case h :: t => t.foldLeftM[({ type L[x] = State[S, x] })#L, T](h)(op)
  case Nil => ???
}

К сожалению, в обоих случаях параметры типа необходимы (вывод типа здесь не работает), поэтому вы, вероятно, захотите определить псевдоним типа и избежать лямбда-выражения типа, если бы вы часто делали подобные вещи.

person Travis Brown    schedule 19.12.2015
comment
Думаю, можно использовать и небезопасный вариант: list.flatMap(l => l.tail.foldLeftM(l.head)(op)) - person Kolmar; 20.12.2015
comment
@Kolmar Если вы достаточно заботитесь о безопасности, чтобы мириться с государственной монадой, это вряд ли станет чем-то, что вы бы выбрали. - person Travis Brown; 20.12.2015
comment
@TravisBrown Работает отлично, большое спасибо. На самом деле я был довольно близок к решению, но попытался решить проблему вывода типа, используя псевдоним типа вместо лямбда типа. Сбой компиляции из-за отсутствия свидетельства Monad для псевдонима моего типа - person Magnus Eklund; 20.12.2015