2012-03-15 27 views
14

Tôi cần phải sử dụng biến danh sách đơn nguyên. Tôi đã đọc rằng có các sự cố có thể xảy ra với ListT IO từ Control.Monad.List, vì IO không giao hoán, vì vậy, tôi đang xem ListT done right. Nhưng tôi nhận được một số hành vi bất ngờ.danh sách biến áp đơn nguyên

xem xét kiểm tra đơn giản này:

test = runListT $ do 
    x <- liftList [1..3] 
    liftIO $ print x 
    y <- liftList [6..8] 
    liftIO $ print (x,y) 

Sử dụng Control.Monad.List:

Main> test 
1 
(1,6) 
(1,7) 
(1,8) 
2 
(2,6) 
(2,7) 
(2,8) 
3 
(3,6) 
(3,7) 
(3,8) 
[(),(),(),(),(),(),(),(),()] 

Sử dụng "ListT thực hiện ngay":

Main> test 
1 
(1,6) 

Đây có phải là một vấn đề với " ListT thực hiện đúng ", hoặc tôi chỉ sử dụng nó sai? Có lựa chọn thay thế nào khác không?

Cảm ơn!

Trả lời

8

Điều này có thể intensional trên một phần của tác giả, vì họ nói

nó cho phép mỗi phần tử của danh sách có tác dụng phụ riêng của mình, mà chỉ nhận được 'excecuted' nếu yếu tố này của danh sách thực sự được kiểm tra.

Tôi không chắc chắn. Dù sao, bạn có thể sử dụng chức năng này để xâu chuỗi lại toàn bộ danh sách :

runAll_ :: (Monad m) => ListT m a -> m() 
runAll_ (ListT m) = runAll_' m where 
    runAll_' m = do 
     mm <- m 
     case mm of 
      MNil   -> return() 
      _ `MCons` mxs -> runAll_' mxs 

Và một tương tự runAll mà trả về một danh sách nên dễ xây dựng.

main = runAll_ $ do 
    x <- liftList [1..3] 
    liftIO $ print x 
    y <- liftList [6..8] 
    liftIO $ print (x,y) 

1 
(1,6) 
(1,7) 
(1,8) 
2 
(2,6) 
(2,7) 
(2,8) 
3 
(3,6) 
(3,7) 
(3,8) 
+0

Hmm, ok điều này có ý nghĩa và ý tưởng 'runAll_' của bạn khá hay! Tôi đã mong đợi hành vi tương tự như lồng nhau cho các vòng với các câu lệnh in trong một ngôn ngữ bắt buộc. Nhưng nếu "ListT thực hiện đúng" là lười biếng, tại sao nó vẫn thực hiện tác dụng phụ cho người đứng đầu danh sách? –

+0

Giả sử bạn luôn muốn ít nhất là phần tử đầu tiên, vì vậy nó kết thúc tốt đẹp "toàn bộ danh sách" trong 'm', và cũng bao bọc cdr trong' m'; chiếc xe không được bọc. Nếu bạn sắp xếp chuỗi "toàn bộ danh sách", nó sẽ chỉ hiển thị ô tô. – Owen

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