2011-12-13 23 views
5

Estoy intentando comenzar a usar scalaz en mi proyecto de elevación. Para ese propósito estoy reescribiendo un código para cumplir con el estilo. Considere un código para iniciar sesión en un usuario:Intentando entender la mónada del estado de Scalaz

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) 
    } 

Por lo tanto, esto se debe volver a escribir utilizando una mónada de estado de alguna manera. Pero simplemente no entiendo, cómo. Intentar esto:

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: ejemplo Actualizado, de acuerdo con las respuestas.

¿Algún buen tutorial/explicación sobre las mónadas estatales en scalaz, que muestra cómo usar gets, put, etc.?

+0

¿Echa un vistazo a mi pregunta/respuesta anterior? http://stackoverflow.com/questions/7734756/scalaz-state-monad-examples – huynhjl

+2

No estoy seguro de que esto sea realmente práctico.No puedes simplemente usar una mónada de estado y deshacerte mágicamente de todas las 'var's en tu código. Para que esto funcione, debe tener algunos medios para encadenar los cambios de estado que los métodos de devolución de llamada de 'SHtml' de Lift no admiten. (Creo que todo el concepto de Lift es precisamente que utilizas variables ocultas en muchos cierres). Sin embargo, me alegraría que se probara que estoy equivocado y ver un ejemplo práctico de esto. – Debilski

+0

Tienes razón. Gracias. – folone

Respuesta

2

Advertencia: nunca he usado la mónada del estado de Scala. Sin embargo, creo que veo la razón por la que se comporta como dices.

onSubmit ve el viejo pass, no la que, estoy put 'ting

Bueno, mira lo que está haciendo:

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

En primer lugar, no lo hago piensas que estás poniendo lo que piensas que estás poniendo. Tal vez puedas probar:

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

En segundo lugar, no creo que está recibiendo lo que usted piensa que está recibiendo. No tengo ni idea de cómo funciona mónada estado Scalaz, pero debe ser algo así:

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

No creo que se utiliza para referirse a pass el estado cambiante; pass es simplemente el valor que se le da al cálculo del estado para empezar, lo que explicaría por qué User.logIn("username", pass) está usando la palabra clave "vieja".

También (aunque no sé SHtml o lo que & hace) Dudo mucho que esto realmente funcione. Es difícil explicar por qué pienso esto, pero tiene algo que ver con SHtml, probablemente no siendo amigable con la construcción de expresiones de estado dentro de sí mismo, como comentó Debilski. SHtml.password parece que espera que le dé una función arbitrariamente de efecto secundario; esta elección de diseño inmediatamente lo hace antipático a un enfoque funcional para lo que está intentando hacer.

+1

Esta es una respuesta incompleta y posiblemente horrible. Aquellos que realmente saben acerca de Lift y scalaz: por favor vote/comente según corresponda para confirmar/negar mis conclusiones. –

2

Los mejores ejemplos scalaz que he encontrado hasta el momento son los siguientes: http://etorreborre.blogspot.com/2011/06/essence-of-iterator-pattern.html?m=1 http://etorreborre.blogspot.com/2011/12/pragmatic-io.html?m=1 y el seguimiento de UPS. Este ejemplo de ejemplos de scalaz :) https://github.com/scalaz/scalaz/blob/scalaz-seven/example/src/main/scala/scalaz/example/WordCount.scala

En el ejemplo de recuento de palabras, cuenta 3 valores y el valor de la palabra se calcula mediante el uso del estado. Espero que esto ayude.

Cuestiones relacionadas