Пытаюсь понять монаду состояния скалаза - PullRequest
5 голосов
/ 13 декабря 2011

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

  def login: CssSel = {
    var password = ""
    def submit() {
      if (doLogin) S.redirectTo("/index")
      else S.error("Wrong password")
    }
    "name=pwd"    #> SHtml.password(password, password = _) &
    "type=submit" #> SHtml.onSubmitUnit(submit)
  }

Итак, это нужно как-то переписать, используя монаду состояния.Но я просто не понимаю, как.Попробуем это:

val result = for {
    s       <- init[String]
    pass    <- SHtml.password(s, put(_))
    newPass <- init[String]
    res     <- "name=pwd"    #> pass &
               "type=submit" #> SHtml.onSubmit { _ =>
                 if (User.logIn("username", newPass)) S.redirectTo("/index")
                 else S.error("Wrong password")
               }
} yield (newPass, res)
result ! ""

UPD: Обновлен пример, согласно ответам.

Любые хорошие уроки / объяснения монад состояний в скалазе, показывающие, как использовать gets, put и т.д?

Ответы [ 2 ]

2 голосов
/ 14 декабря 2011

Предупреждение: я никогда не использовал государственную монаду Scala.Тем не менее, я думаю, что вижу причину, по которой вы ведете себя так, как вы говорите.

onSubmit видит старый pass, а не тот, я put 'ting

Хорошо, посмотрите на то, что вы делаете:

... { pass =>
  ... SHtml.password(pass, _ => put(pass))
  ... User.logIn("username", pass)
}

Во-первых, я не думаю, что вы ставите то, что, как вы думаете, вы вкладываете.Попробуйте вместо этого:

... SHTML.password(pass, newPass => put(newPass))

Во-вторых, я не думаю, что вы получаете то, что, как вы думаете, вы получаете.Я понятия не имею, как работает монада состояний Scalaz, но она должна быть что-то примерно так:

... User.logIn("username", get())

Я не думаю, что вы используете pass для обозначения изменяющегося состояния;pass - это просто значение, которое дается для начального вычисления состояния, что объясняет, почему User.logIn("username", pass) использует «старый» oassword.

Также (хотя я не знаю SHtmlили что & делает) Я очень сомневаюсь, что это на самом деле будет работать.Трудно объяснить, почему я так думаю, но это как-то связано с тем, что SHtml, вероятно, не дружит с созданием выражений состояний внутри себя, как прокомментировал Дебилски.SHtml.password кажется, ожидают , что вы дадите ему произвольную побочную функцию;этот выбор дизайна сразу делает его неприемлемым для функционального подхода к тому, что вы пытаетесь сделать.

2 голосов
/ 13 декабря 2011

Лучшие примеры скаляза, которые я нашел до сих пор, это: http://etorreborre.blogspot.com/2011/06/essence-of-iterator-pattern.html?m=1 http://etorreborre.blogspot.com/2011/12/pragmatic-io.html?m=1 И последующие действия.Этот пример из примеров скалаза :) https://github.com/scalaz/scalaz/blob/scalaz-seven/example/src/main/scala/scalaz/example/WordCount.scala

В примере подсчета слов он насчитывает 3 значения, а значение подсчета слов рассчитывается с использованием состояния.Надеюсь, это поможет.

...