I'm trying to start using scalaz in my lift project. For that purpose I'm rewriting some code to meet the style. Consider a code for logging in a user:
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)
}
So, this should be rewritten using a state monad somehow. But I just don't get, how. Trying this:
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: Updated example, according to answers.
Any good tutorials/explanations on state monads in scalaz, showing how to use gets
, put
, etc?
Warning: I've never used the Scala state monad. However, I think I see the reason it behaves as you say it does.
onSubmit
sees the oldpass
, not the one, I'mput
'ting
Well, look at what you are doing:
... { pass =>
... SHtml.password(pass, _ => put(pass))
... User.logIn("username", pass)
}
Firstly, I don't think you are putting what you think you're putting. Try this instead:
... SHTML.password(pass, newPass => put(newPass))
Secondly, I don't think you are getting what you think you're getting. I have no clue how Scalaz state monad works, but it should be something like this:
... User.logIn("username", get())
I don't think that you use pass
to refer to the changing state; pass
is simply the value that is given to the state computation to begin with, which would explain why User.logIn("username", pass)
is using the "old" oassword.
Also (though I don't know SHtml
or what &
does) I highly doubt this will actually work. It's hard to explain why I think this, but it has something to do with SHtml
probably not being friendly with constructing state expressions inside of itself, as Debilski commented. SHtml.password
seems to expect you to give it an arbitrarily side-effecting function; this design choice immediately makes it unfriendly to a functional approach for the thing you are attempting to do.
The best scalaz examples I have found so far are these: http://etorreborre.blogspot.com/2011/06/essence-of-iterator-pattern.html?m=1 http://etorreborre.blogspot.com/2011/12/pragmatic-io.html?m=1 And the follow ups. This example from scalaz examples :) https://github.com/scalaz/scalaz/blob/scalaz-seven/example/src/main/scala/scalaz/example/WordCount.scala
In the word count example it counts 3 values and the wordcount value is calculated through using state. I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With