2011-12-13 54 views
5

Tôi đang cố bắt đầu sử dụng scalaz trong dự án nâng của tôi. Vì mục đích đó, tôi viết lại một số mã để đáp ứng phong cách. Xem xét mã để đăng nhập vào một người dùng:Đang cố gắng hiểu đơn vị trạng thái vô hướng

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

Vì vậy, điều này nên được viết lại bằng cách sử dụng một đơn vị trạng thái nào đó. Nhưng tôi không hiểu, làm thế nào. Cố gắng này:

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: dụ cập nhật, theo câu trả lời.

Bất kỳ hướng dẫn/giải thích tốt nào về các đơn vị trạng thái ở đại lượng, cho biết cách sử dụng gets, put, v.v ...?

+0

Bạn đã xem câu hỏi/câu trả lời trước đó của tôi chưa? http://stackoverflow.com/questions/7734756/scalaz-state-monad-examples – huynhjl

+2

Tôi không chắc điều này thực sự thực tế.Bạn không thể chỉ sử dụng một số đơn vị nhà nước và kỳ diệu loại bỏ tất cả 'var' trong mã của bạn. Để làm việc này, bạn phải có một số cách để thay đổi trạng thái mà các phương thức gọi lại của 'SHtml' của Lift không hỗ trợ. (Tôi nghĩ rằng toàn bộ khái niệm về Lift chính xác là bạn sử dụng các biến bị ẩn trong nhiều lần đóng.) Tôi rất vui khi được chứng minh là sai, và xem một ví dụ làm việc về điều này. – Debilski

+0

Bạn nói đúng. Cảm ơn. – folone

Trả lời

2

Cảnh báo: Tôi chưa từng sử dụng đơn vị trạng thái Scala. Tuy nhiên, tôi nghĩ rằng tôi thấy lý do nó hoạt động như bạn nói nó.

onSubmit thấy cái cũ pass, không phải là người, tôi put 'ting

Vâng, nhìn vào những gì bạn đang làm:

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

Thứ nhất, tôi không nghĩ rằng bạn đang đặt những gì bạn nghĩ rằng bạn đang đặt. Hãy thử thay thế này:

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

Thứ hai, tôi không nghĩ bạn đang nhận được những gì bạn nghĩ mình đang nhận được. Tôi không có đầu mối như thế nào đơn nguyên nhà nước Scalaz hoạt động, nhưng nó phải là một cái gì đó như thế này:

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

Tôi không nghĩ rằng bạn sử dụng pass để đề cập đến tình trạng thay đổi; pass chỉ đơn giản là giá trị được đưa ra để tính toán trạng thái bắt đầu, điều này sẽ giải thích tại sao User.logIn("username", pass) đang sử dụng mật khẩu "cũ".

Ngoài ra (mặc dù tôi không biết SHtml hoặc những gì & làm) Tôi rất nghi ngờ điều này thực sự sẽ hoạt động. Thật khó để giải thích lý do tại sao tôi nghĩ rằng điều này, nhưng nó có một cái gì đó để làm với SHtml có lẽ không được thân thiện với xây dựng biểu thức trạng thái bên trong của chính nó, như Debilski nhận xét. SHtml.password có vẻ như mong đợi bạn để cho nó một chức năng phụ tùy ý; lựa chọn thiết kế này ngay lập tức làm cho nó không thân thiện với một cách tiếp cận chức năng cho điều bạn đang cố gắng làm.

+1

Đây là câu trả lời không đầy đủ và có thể là khủng khiếp. Những người thực sự biết về Lift và scalaz: xin vui lòng bình chọn/bình luận thích hợp để xác nhận/từ chối kết luận của tôi. –

2

Các ví dụ scalaz tốt nhất mà tôi đã tìm thấy cho đến nay là những: http://etorreborre.blogspot.com/2011/06/essence-of-iterator-pattern.html?m=1 http://etorreborre.blogspot.com/2011/12/pragmatic-io.html?m=1 Và sau up. Ví dụ này từ ví dụ về hình ảnh đại diện :) https://github.com/scalaz/scalaz/blob/scalaz-seven/example/src/main/scala/scalaz/example/WordCount.scala

Trong ví dụ đếm từ, nó tính 3 giá trị và giá trị số từ được tính toán thông qua trạng thái sử dụng. Tôi hi vọng cái này giúp được.

Các vấn đề liên quan