2011-12-13 21 views
5

Asansör projemde scalaz kullanmaya başladım. Bu amaçla, stili karşılamak için bazı kodları yeniden yazıyorum. Bir kullanıcı giriş için bir kod düşünün:Scalaz state monad'ı anlamaya çalışmak

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

Yani, bu şekilde bir devlet monad kullanılarak yeniden yazılmalıdır. Ama sadece anlamıyorum, nasıl. bu çalışılıyor:

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: Güncelleme örnek, cevaplarına göre.

Scalaz'taki devlet monad'ları ile ilgili iyi dersler/açıklamalar, gets, put, vb.

+0

Daha önceki sorularıma/cevabınıza bir göz attınız mı? http://stackoverflow.com/questions/7734756/scalaz-state-monad-examples – huynhjl

+2

Bunun gerçekten pratik olduğundan emin değilim.Bazı eyalet monadlarını kullanamazsınız ve kodunuzdaki tüm varyasyonlardan sihirli bir şekilde kurtulamazsınız. Bunun çalışması için, Lift'in SHtml'inin geri çağırma yöntemlerinin desteklemediği durum değişikliklerini zincirlemenin bir yolu olmalıdır. (Bence Lift'in bütün konsepti, birçok kapanışta gizli değişkenleri kullanmanızdır.) Yine de yanlış olduğunu kanıtlamaktan mutluluk duyarım ve bunun çalışma örneğini görürsünüz. – Debilski

+0

Haklısınız. Teşekkürler. – folone

cevap

2

Uyarı: Scala state monad'ını hiç kullanmadım. Ancak bence söylediği gibi davrandığını görüyorum.

onSubmit, ben put 'ting

Eh olduğum eski pass, bir değil görür, ne yapıyorsun bakmak: Öncelikle

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

, bilmiyorum koyduğunuzu düşündüğünüzü düşündüğünüzü düşünün. Bunun yerine şunu deneyin:

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

İkinci olarak, aldığınızı düşündüğünüz şeyi aldığınızı düşünmüyorum. Ben Scalaz devlet monad nasıl çalıştığını hiçbir ipucu var, ama böyle şey olmalıdır:

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

Sana değişen duruma başvurmak için pass kullandığını düşünmüyorum; pass, başlangıç ​​durumuna göre durum hesaplamasına verilen değerdir; bu, neden User.logIn("username", pass)'un "eski" anahtar sözcüğünü kullandığını açıklar.

Ayrıca (SHtml'u veya &'un ne yaptığını bilmeme rağmen) bunun gerçekten işe yarayacağından kuşkuluyum. Bunu neden düşündüğümü açıklamak zor, ama Debillski'nin de belirttiği gibi, SHtml ile kendi içlerinde devlet ifadeleri inşa etme konusunda dostça davranmama ihtimali var. SHtml.password, 'un modelini rasgele bir yan etki işlevi görmesini beklemektedir; Bu tasarım tercihi, bunu yapmaya çalıştığınız şey için işlevsel bir yaklaşımla arkadaşça yapar.

+1

Bu eksik ve muhtemelen korkunç bir cevaptır. Lift ve scalaz hakkında aslında bilenler: sonuçlarımı onaylamak/reddetmek için lütfen uygun şekilde oy verin. –

2

bulduğum en iyi scalaz örnekleri bugüne kadar bunlar: http://etorreborre.blogspot.com/2011/06/essence-of-iterator-pattern.html?m=1 http://etorreborre.blogspot.com/2011/12/pragmatic-io.html?m=1 Ve takip çekimler. scalaz örneklerden Bu örnek, :) kelime https://github.com/scalaz/scalaz/blob/scalaz-seven/example/src/main/scala/scalaz/example/WordCount.scala

bu 3 değerlerini hesaplar ve wordCount değeri durumunu kullanarak üzerinden hesaplanan örnek sayısı. Umarım bu yardımcı olur.

İlgili konular