Tôi đã sử dụng zipSinks :: Monad m => Sink i m r -> Sink i m r' -> Sink i m (r, r')
cho điều này nhưng bị coi là không dùng nữa.Cách ưa thích để kết hợp hai bồn rửa là gì?
Trả lời
((Các gói phần mềm là conduit-0.5.2.3. Toàn bộ module chỉ là để tương thích ngược.))
[chỉnh sửa]
Vì vậy, đoán monadic đơn giản của tôi (xem dưới đây) dường như là sai, mặc dù các loại là chính xác. Bây giờ, tôi chỉ có thể đoán rằng câu trả lời là:
Các tính năng thay thế vẫn đang được phát triển, khá nhiều giống như tất cả ống/Conduit và các khái niệm và các thư viện tương tự.
Tôi sẽ đợi API tiếp theo giải quyết câu hỏi này và vẫn sử dụng zipSink
cho đến lúc đó. (Có lẽ nó đã được chỉ đặt không đúng chỗ.)
[/chỉnh sửa]
tôi không phải là quen với gói này, nhưng nó sẽ không làm chỉ giống như này?
zipSinks :: Monad m => Sink i m r -> Sink i m r' -> Sink i m (r, r')
zipSinks s1 s2 = (,) <$> s1 <*> s2
Sau cùng, tất cả là Monad. (Functor, Applicative)
zipSinks :: Monad sink => sink r -> sink r' -> sink (r, r')
zipSinks s1 s2 = liftM2 (,) s1 s2
Các loại là ok, nhưng không phải là ngữ nghĩa. Phiên bản 'zipSinks' của bạn sẽ chạy chìm liên tiếp và bồn rửa đầu tiên sẽ tiêu thụ hoàn toàn nguồn. – tymmym
Sửa
Sau khi xem xét này, tôi không nghĩ rằng nó có thể với phiên bản hiện tại của Data.Conduit. Ống không phải là Danh mục, do đó, &&&
không nằm trong câu hỏi. Và không có cách nào mà tôi có thể nghĩ đến để kéo kết quả từ thượng nguồn, cho chúng tăng dần lên cả hai bồn rửa và ngắn mạch khi bồn rửa đầu tiên kết thúc. (Mặc dù tôi không nghĩ rằng ngắn mạch theo cách này, nó có vẻ như nó sẽ rất hấp dẫn.) Ngoại trừ tất nhiên, để phù hợp với mô hình trên cả hai Sinks (như zipSinks
trong gói), nhưng đó là những gì chúng tôi cố gắng tránh ở đây.
Điều đó nói rằng, tôi sẽ yêu thích để được chứng minh là sai ở đây.
Nó không đẹp, nhưng bạn có thể làm điều này một cách rõ ràng.
nhập khẩu đầu tiên:
module Main where
import Control.Monad.Trans
import Data.Conduit
import qualified Data.Conduit.Binary as CB
import qualified Data.Conduit.List as CL
import qualified Data.Conduit.Text as CT
import qualified Data.Conduit.Util as CU
import Data.Maybe
import Data.Text (unpack)
Bây giờ cho zipSinks
. Về cơ bản, bạn muốn tạo một bồn rửa kéo đầu vào từ phía trên và gửi nó đến từng bồn rửa riêng biệt. Trong trường hợp này, tôi đã sử dụng CL.sourceList
để thực hiện việc này. Nếu await
trả về Nothing
, maybeToList
trả về một danh sách trống, vì vậy các bồn rửa trẻ em cũng được chạy mà không có đầu vào. Cuối cùng, đầu ra của mỗi bồn rửa trẻ em sau đó được đưa vào tuple.
zipSinks :: Monad m => Sink i m r -> Sink i m r' -> Sink i m (r, r')
zipSinks s1 s2 = do
l <- fmap maybeToList await
o1 <- lift $ CL.sourceList l $$ s1
o2 <- lift $ CL.sourceList l $$ s2
return (o1, o2)
Dưới đây là một số ví dụ về cách sử dụng zipSinks
. Nó xuất hiện để làm việc tốt cả bên trong của IO
và bên ngoài của nó, và trong vài bài kiểm tra tôi đã làm, đầu ra phù hợp với đầu ra của zipped'
, tạo ra bằng cách sử dụng cũ zipSinks
.
doubleHead :: Monad m => Sink Int m (Maybe Int)
doubleHead = await >>= return . fmap (2*)
-- old version
zipped' :: Monad m => Sink Int m (Maybe Int, Maybe Int)
zipped' = CU.zipSinks CL.head doubleHead
-- new version
zipped :: Monad m => Sink Int m (Maybe Int, Maybe Int)
zipped = zipSinks CL.head doubleHead
fromList = CL.sourceList [7, 8, 9] $$ zipped
-- (Just 7, Just 14)
fromFile :: String -> IO (Maybe Int, Maybe Int)
fromFile filename = runResourceT $
CB.sourceFile filename
$= CB.lines
$= CT.decode CT.utf8
$= CL.map (read . unpack)
$$ zipped
-- for a file with the lines:
--
-- 1
-- 2
-- 3
--
-- returns (Just 1, Just 2)
Tuyệt vời! (NB, bạn có thể viết 'await >> = return. Fmap (2 *)' cho 'doubleHead', và tương tự,' l <- fmap maybeToList chờ đợi thay vì sử dụng 'input' trong' zipSinks'. Data.Conduit.Internals' một nhập khẩu không liên quan?) – huon
Vâng, tôi nhận ra rằng tôi có lẽ có thể đã sử dụng functors ở một số nơi. Tôi vẫn còn đủ một n00b tại Haskell rằng đó là một bản chỉnh sửa thứ hai cho tôi, thật không may. Và có, 'Data.Conduits.Internals' là không liên quan. Ban đầu, tôi đã xem xét sử dụng 'sinkToPipe' từ nó. Cảm ơn bạn đã chỉ ra những điều này. Tôi sẽ cập nhật câu trả lời. – Eric
Phiên bản 'zipSinks' của bạn chỉ kết hợp các yếu tố đầu tiên. Ví dụ 'runResourceT $ CL.sourceList [1,2,3] $$ zipSinks (CL.take 2) (CL.take 2)' sẽ trả về '([1], [1])' nhưng nên '([1] , 2], [1,2]) '. – tymmym
- 1. cách ưa thích để triển khai hashCode() là gì?
- 2. Cách ưa thích để preallocate mảng NumPy là gì?
- 3. Cách ưa thích để thụt lề các trường hợp trong một công tắc là gì?
- 4. Cách ưa thích của chuỗi chức năng Underscore.js là gì?
- 5. Cách ưa thích để kết nối với cơ sở dữ liệu postgresql từ PHP là gì?
- 6. bồn rửa đầu ra độc lập với nền tảng/dev/null cho Java
- 7. Cách ưa thích để sử dụng favicon?
- 8. Cách thích hợp để định dạng thẻ JavaScript là gì?
- 9. Cách ưa thích để đính kèm AudioEffect vào kết hợp toàn cầu?
- 10. Phần mở rộng tệp Pascal ưa thích là gì?
- 11. Thư viện mẫu ưa thích cho jQuery là gì?
- 12. Cách ưa thích để làm mẫu trang web và chủ đề với Wicket là gì?
- 13. Đường ống GStreamer với nhiều bồn rửa UDP (bao gồm hình ảnh)
- 14. Đồ thị: tìm bồn rửa dưới O (| V |) - hoặc không thể hiển thị nó ở
- 15. Cách thích hợp để sử dụng jQuery kết hợp với 'sử dụng nghiêm ngặt' là gì?
- 16. Cách thích hợp để chuyển hướng lại là gì?
- 17. Cách ưa thích để quản lý đơn đặt hàng trong mẫu trình xây dựng là gì?
- 18. Cách nhanh nhất/ưa thích để lưu trữ dữ liệu tĩnh trong Android là gì?
- 19. Cách ưa thích để trả về một bảng trống trong SQL là gì?
- 20. Cách ưa thích để thoát khỏi chương trình dòng lệnh là gì?
- 21. Cách ưa thích để trả về phản hồi JSON trống trong Rails 3 là gì?
- 22. Cách thích hợp để thụt lề Erlang là gì?
- 23. Cách ưa thích để tạo tín hiệu tín hiệu kết hợp với tín hiệu và hoàn thành khi hoàn thành hoặc lỗi là gì?
- 24. Cách ưa thích của bạn trong việc thử nghiệm đoạn mã javascript là gì?
- 25. Cách thích hợp để bao bọc [NSString stringWithFormat:] là gì?
- 26. MVC3 + Ninject: Cách thích hợp để tiêm User IPrincipal là gì?
- 27. Cách ưa thích của bạn đối phó với phát triển đa nền tảng là gì?
- 28. Phong cách ưa thích của bạn cho các biến đặt tên trong R là gì?
- 29. Cách thích hợp để đảm bảo kết nối EntityManager bị đóng là gì?
- 30. Cách thích hợp để xử lý các kết nối JDBC với Spring và DBCP là gì?
Hành vi nào, * chính xác *, bạn có muốn các bồn "kết hợp" có? Tôi đã thử xem tài liệu cũ và thực hiện 'zipSinks', nhưng hành vi này không dễ nhận thấy trong nháy mắt. –
@DanBurton: 'zipSinks' mất hai Sinks và trả về một Sink tạo ra một cặp với kết quả của Sinks tương ứng. Ví dụ 'sizeCrc32Sink = zipSinks sizeSink crc32Sink' sẽ đếm kích thước và tổng kiểm tra. Tôi hành vi tương tự như được mô tả bởi Oleg [ở đây] (http://okmij.org/ftp/Streams.html#1enum2iter). – tymmym
Ok tôi thấy; nó về cơ bản móc lên những chờ đợi và nguồn cấp dữ liệu đầu ra thượng nguồn cho cả hai bồn cùng một lúc, loại forking dòng đầu vào trong hai. Các tài liệu cho Data.Conduit.Util nói rằng "có những cách dễ dàng hơn để xử lý các trường hợp sử dụng của chúng" nhưng tôi thấy không có cách nào dễ dàng hơn cho trường hợp sử dụng này, vì nó yêu cầu delving vào ruột ruột để thực hiện. –