Tôi đang tìm một hàm cơ bản giống như mapM
trên danh sách - nó thực hiện một chuỗi các hành động đơn thuần lấy mọi giá trị trong danh sách dưới dạng tham số - và mỗi hàm monadic trả về m (Maybe b)
. Tuy nhiên, tôi muốn nó dừng sau thông số đầu tiên làm cho hàm trả về giá trị Just
, không thực hiện thêm bất kỳ giá trị nào sau đó và trả về giá trị đó.triển khai "findM" trong Haskell?
Vâng, nó có lẽ sẽ dễ dàng hơn để chỉ hiển thị chữ ký loại:
findM :: (Monad m) => (a -> m (Maybe b)) -> [a] -> m (Maybe b)
nơi b là giá trị đầu tiên Just
. Các Maybe
trong kết quả là từ các find
ing (trong trường hợp của một danh sách trống, vv), và không có gì để làm với các Maybe
trả lại bởi chức năng Monadic.
Tôi dường như không thể thực hiện điều này bằng ứng dụng thư viện đơn giản. Tôi có thể sử dụng
findM f xs = fmap (fmap fromJust . find isJust) $ mapM f xs
mà sẽ làm việc, nhưng tôi đã thử nghiệm này và có vẻ như tất cả trong những hành động monadic được thực hiện trước khi gọi find
, vì vậy tôi không thể dựa vào sự lười biếng ở đây.
ghci> findM (\x -> print x >> return (Just x)) [1,2,3]
1
2
3
-- returning IO (Just 1)
Cách tốt nhất để triển khai chức năng này sẽ không thực thi các hành động đơn thuần sau lần trả lại "chỉ" đầu tiên là gì? Một cái gì đó mà có thể làm:
ghci> findM (\x -> print x >> return (Just x)) [1,2,3]
1
-- returning IO (Just 1)
hoặc thậm chí, lý tưởng,
ghci> findM (\x -> print x >> return (Just x)) [1..]
1
-- returning IO (Just 1)
Hy vọng rằng có một câu trả lời mà không sử dụng đệ quy rõ ràng, và là tác phẩm của các chức năng thư viện nếu có thể? Hoặc thậm chí có thể là điểm miễn phí một?
Hah! Có vẻ như chúng tôi đã có cùng một ý tưởng cùng một lúc. Bạn đã có một chút nhanh hơn mặc dù. :) – shang
Có. 'mzero' và' mplus' trong cá thể 'MonadPlus' cho' Có thể' giống hệt 'rỗng' và' <|> 'trong trường' Thay thế' cho 'Có thể'. 'Có lẽ' 'mzero' và' mplus' là 'return Nothing' và hàm '<||>' mà tôi đã định nghĩa, ngoại trừ được viết với một trường hợp như câu trả lời ban đầu của tôi và câu trả lời của jozefg. Tất cả những gì chúng ta bỏ lỡ cho một luận thuyết hoàn chỉnh về chủ đề này là một lời giải thích về cách đi từ nhìn thấy '(Monad m) => m. f' để viết một biến áp monad cho f để bạn có thể thay thế 'm. f' với một kiểu dữ liệu mới để bạn có thể bắt đầu viết các thể hiện cho nó. – Cirdec
@Cirdec Tôi đã cập nhật câu trả lời.Trong trường hợp chung, có thể không thể xây dựng một biến thế như vậy, nhưng chúng ta không thực sự cần một máy biến áp. Đó là đủ để có một monoid và gấp nó. –