2010-09-24 26 views
13

Có một ký hiệu thanh lịch cho Currying các đối số của một chức năng ra khỏi trật tự trong Haskell?Currying ra lệnh trong Haskell

Ví dụ, nếu bạn muốn chia 2 bởi tất cả các yếu tố của một danh sách, bạn có thể viết

map ((/) 2) [1,2,3,4,5] 

Tuy nhiên để phân chia tất cả các yếu tố của một danh sách có vẻ như bạn cần phải xác định một chức năng ẩn danh

map (\x -> x/2) [1,2,3,4,5] 

Chức năng ẩn danh nhanh chóng trở nên khó sử dụng trong các trường hợp phức tạp hơn. Tôi biết rằng trong trường hợp này bản đồ ((*) 0.5) [1,2,3,4,5] sẽ hoạt động tốt, nhưng tôi quan tâm để biết nếu Haskell có một cách thanh lịch hơn currying đối số của một chức năng ra khỏi trật tự?

+0

'flip' và backticks là tốt cùng với chỉ đơn giản bằng cách sử dụng chức năng infix (như delnan chỉ ra). –

Trả lời

16

Trong trường hợp đặc biệt này:

Prelude> map (/2) [1..5] 
[0.5,1.0,1.5,2.0,2.5] 

Không chỉ bạn có thể sử dụng một nhà điều hành ghi như chức năng tiền tố bình thường, bạn cũng có thể phần nào áp dụng nó ở dạng trung tố. Tương tự như vậy, ví dụ đầu tiên tốt hơn sẽ được viết là map (2/) [1..5]

Ngoài ra, có flip không hoàn toàn thanh lịch, nhưng vẫn là tùy chọn tốt nhất có sẵn cho các chức năng thông thường (khi bạn không muốn biến chúng thành nội dung thông qua backticks) :

Prelude> let div' = (/) 
Prelude> div' 2 1 
2.0 
Prelude> flip div' 2 1 
0.5 
+0

Tính năng này chỉ hoạt động với các toán tử? Điều gì về chức năng tùy ý? – Gabe

+0

@Gabe: Như FUZxxl đã viết, nó cũng hoạt động với các chức năng được sử dụng infix (bằng cách bao quanh chúng với backticks). Tôi sẽ cung cấp một ví dụ, nhưng ông đã cung cấp một ví dụ. – delnan

+0

Cảm ơn bạn.Đó là một sự xấu hổ không có cú pháp như f 1 2 # 4 #, có tác dụng tương tự như \ x y -> f 1 2 x 4 y. – hosiers

2

Đối với một thứ hai của bạn, lambda là không cần thiết, chỉ cần sử dụng như:

map (/2) [1..5] 

dạng (/ 2) đơn giản có nghĩa, mà bạn muốn truy cập vào param thứ hai của một nhà điều hành. Cũng có thể với đối số đầu tiên (2/). Điều này được gọi là một phần , và là một hack thực sự hữu ích, không chỉ trong golf mã. Bạn cũng có thể sử dụng nó trong các chức năng tiền tố, nếu bạn sử dụng chúng Infix:

map (`div` 2) [1..5] 

Trong những trường hợp khó khăn hơn, như 3 hoặc nhiều đối số, bạn phải sử dụng lambdas, khi nó trở nên hầu hết thời gian dễ đọc hơn.

2

Tôi nghĩ bạn đang tìm kiếm giải pháp tổng quát, như sơ đồ cut. Đúng?

Có chức năng flip rằng đảo ngược 2 đối số đầu tiên của hàm. Có thể có các chức năng khác đang thực hiện một nhiệm vụ tương tự (tôi không quá giỏi ở Haskell ...).

+1

'lật' không đảo ngược danh sách đối số. Nó chỉ lật hai cái đầu tiên, xem xét điều này: 'flip (.) :: (a -> b) -> (b -> c) -> a -> c'. -1 – fuz

0

tôi gặp phải một very similar issue bản thân mình thời gian gần đây, và tôi đã không thể tìm thấy một giải pháp thanh lịch khác vì sử dụng một hàm helper để làm điều đó:

dbfunc f b c = (\a -> liftIO $ f a b c) 
deleteAllRows = do 
    ask >>= dbfunc run "delete from t1" [] 

Ít nhất mô hình này là phổ biến đủ trong HDBC rằng dbfunc có thể tái sử dụng.

+0

'hỏi >> = liftIO. (flip. (flip run) "xóa từ t1" []) ' – is7s

+0

Đối với một số giá trị thanh lịch ;-) – Gaius

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