Đó là khá dễ dàng để xác định một nhà điều hành nhưNested ứng dụng chức năng
(@) :: [x -> y] -> [x] -> [y]
mà phải mất một danh sách các hàm và một danh sách các đầu vào và trả về một danh sách các kết quả đầu ra. Có hai cách rõ ràng để thực hiện điều này:
- Áp dụng các chức năng đầu tiên vào đầu vào đầu tiên, chức năng thứ hai để các đầu vào thứ hai, vv
- Áp dụng tất cả các chức năng để mỗi đầu vào.
Hoặc là không đáng kể để xác định. Điều tốt đẹp về nó là bây giờ bạn có thể làm điều gì đó như
foo :: X -> Y -> Z -> R
bar :: [X] -> [Y] -> [Z] -> [R]
bar xs ys zs = [foo] @@ xs @@ ys @@ zs
Điều này nói chung với một số đối số chức năng tùy ý.
Cho đến nay rất tốt. Bây giờ cho các vấn đề: Làm thế nào để tôi thay đổi chữ ký kiểu cho @@
như vậy mà các loại chữ ký cho bar
trở thành
bar :: [X] -> [Y] -> [Z] -> [[[R]]]
Nó không khó để thực hiện một chức năng với loại hình này; một trong hai cách này sẽ làm điều đó:
bar xs ys zs = map (\ x -> map (\ y -> map (\ z -> foo x y z) zs) ys) zs
bar xs ys zs = map (\ z -> map (\ y -> map (\ x -> foo x y z) xs) ys) zs
Tôi không kén chọn kết quả mình nhận được. Nhưng tôi không thể tìm ra cách tinh chỉnh toán tử @@
để thực hiện điều này.
Một điều hiển nhiên phải cố gắng là
(@@) :: [x -> y] -> [x] -> [[y]]
Nó không khó để thực hiện điều này, nhưng nó sẽ không giúp bạn. Bây giờ bạn có
[foo] @@ xs :: [[Y -> Z -> R]]
không phải là đầu vào hợp lệ cho @@
. Không có cách rõ ràng để biết có bao nhiêu cấp độ của danh sách để đạt được thông qua để có được chức năng; rõ ràng cách tiếp cận này là một kết thúc chết.
Tôi đã thử một vài chữ ký có thể có khác, nhưng không có chữ ký nào đưa tôi đến gần câu trả lời hơn. Ai đó có thể cho tôi một giải pháp, hoặc giải thích tại sao không tồn tại?
Sử dụng typeclass. – dave4420
Không liên quan đến câu hỏi, tuy nhiên, bản gốc '(@@)' (phiên bản thứ 2) tương đương với cá thể 'Áp dụng' cho danh sách. Phiên bản đầu tiên, áp dụng từng hàm cho mỗi đầu vào, là cá thể 'Applicative' cho kiểu mới' ZipList'. –
Sự khác biệt giữa 'mỗi' và 'mọi' là gì? – Prateek