Giả sử tôi có một chức năng với chữ ký loại sau đây:Sử dụng các mục trong một danh sách như các đối số
g :: a -> a -> a -> b
Tôi cũng có một danh sách các a
s-chúng ta hãy gọi nó xs
-đó Tôi biết sẽ có ít nhất ba mặt hàng. Tôi muốn áp dụng g
cho ba mục đầu tiên của xs
. Tôi biết tôi có thể xác định một bộ tổ hợp như sau:
($$$) :: (a -> a -> a -> b) -> [a] -> b
f $$$ (x:y:z:_) = f x y z
Sau đó tôi chỉ có thể sử dụng g $$$ xs
. Điều này làm cho $$$
một chút như uncurry
, nhưng đối với một hàm có ba đối số cùng loại và danh sách thay vì một bộ tuple.
Có cách nào để làm điều này một cách tự nhiên bằng cách sử dụng bộ kết hợp tiêu chuẩn? Hay đúng hơn, cách thành ngữ nhất để làm điều này trong Haskell là gì? Tôi nghĩ rằng cố gắng pointfree
trên một phiên bản không infix của $$$
có thể cho tôi một số ý tưởng về nơi để bắt đầu, nhưng đầu ra là một abomination với 10 flip
s, một số ít head
s và tail
s và ap
s và 28 dấu ngoặc đơn.
(NB: Tôi biết điều này không phải là một điều tuyệt vời Haskelly để làm ở nơi đầu tiên, nhưng tôi đã đi qua một vài tình huống mà nó có vẻ như một giải pháp hợp lý, đặc biệt là khi sử dụng Parsec. chắc chắn chấp nhận "không bao giờ làm điều này trong mã thực" nếu đó là câu trả lời tốt nhất, nhưng tôi muốn thấy một số thủ thuật thông minh liên quan đến ((->) r)
đơn nguyên hoặc bất cứ điều gì.)
Tôi không thấy có gì sai với mã bạn có. Đó là ngắn và cho điểm. Không phải tất cả mọi thứ phải (hoặc nên) pointfree. – sepp2k
Tôi không nhất thiết phải nghĩ rằng có bất cứ điều gì sai trái với nó - Tôi chỉ tò mò về việc liệu có một cách ngắn gọn để làm điều này mà không xác định một tổ hợp mới như '$$$'. –
Lưu ý rằng đây là một phần chức năng, vì vậy ... có lẽ là một ý tưởng tồi nói chung :) Bạn có thể tốt hơn với một '($$$) :: (a -> a -> a -> b) -> [a] -> Có thể b' –