Ngoài ra tuple trong pointfree


16

Cách ngắn nhất chúng ta có thể thể hiện chức năng là gì

f(a,b)(c,d)=(a+c,b+d)

trong ký hiệu không có điểm?

pointfree.io cho chúng tôi

uncurry (flip flip snd . (ap .) . flip flip fst . ((.) .) . (. (+)) . flip . (((.) . (,)) .) . (+))

mà với một chút công việc có thể được rút ngắn thành

uncurry$(`flip`snd).((<*>).).(`flip`fst).((.).).(.(+)).flip.(((.).(,)).).(+)

cho 76 byte. Nhưng điều này dường như vẫn thực sự dài và phức tạp cho một nhiệm vụ đơn giản như vậy. Có cách nào chúng ta có thể diễn tả phép cộng theo cặp như một hàm không có điểm ngắn hơn không?

Để rõ ràng theo ý tôi muốn nói là không có điểm, một khai báo hàm không có điểm bao gồm lấy các hàm và toán tử hiện có và áp dụng chúng cho nhau theo cách mà hàm mong muốn được tạo. Backticks, ngoặc và các giá trị văn chương ( [], 0, [1..3], vv) được cho phép nhưng các từ khóa như whereletkhông. Điều này có nghĩa là:

  • Bạn không thể chỉ định bất kỳ biến / chức năng

  • Bạn không thể sử dụng lambdas

  • Bạn không được nhập

Đây là câu hỏi tương tự khi nó là một CMC


9
Tôi không bao giờ hiểu tại sao nó lại được gọi là điểm miễn phí khi nó thực sự đầy điểm. : P
Ông Xcoder


5
Thật đáng tiếc, chúng tôi không được phép nhập gói Haskell tốt nhất , nếu không thì giải pháp sẽ là như vậy (+)***(+).
Silvio Mayolo

2
Một ý tưởng: (+)<$>([1],2)<*>([3],4)cho ([1,3],6).
xnor

2
Tôi đã dành một chút thời gian để cố gắng tạo ra một giải pháp tốt bằng cách sử dụng mẹo của xnor ... nhưng tôi đã kết thúc với rác này . Tôi thậm chí không biết tại sao đôi khi tôi cố gắng ...
hoàn toàn là con người

Câu trả lời:



8

44 byte

-8 byte nhờ rjan Johansen. -3 byte nhờ Bruce Forte.

(.).flip(.)<*>(zipWith(+).)$mapM id[fst,snd]

Hãy thử trực tuyến!

Dịch sang:

f t1 t2 = zipWith (+) (mapM id [fst, snd] $ t1) (mapM id [fst, snd] $ t2)

67 byte

-8 byte nhờ rjan Johansen. -1 byte nhờ Bruce Forte.

Nếu đầu ra tuple là bắt buộc:

(((,).head<*>last).).((.).flip(.)<*>(zipWith(+).)$mapM id[fst,snd])

Hãy thử trực tuyến!

Yup, tôi tự làm nó không tạo ra trái chín. Nhưng tôi hài lòng với việc [a] → (a, a)chuyển đổi.

listToPair  [a]  (a, a)
listToPair = (,) . head <*> last
-- listToPair [a, b] = (a, b)

Bây giờ nếu có một chức năng ngắn với m (a → b) → a → m b.


3
Ghét để phá vỡ nó cho bạn, nhưng mapM id[fst,snd]ngắn hơn.
Ørjan Johansen

Đáng buồn thay, mapM idlà phiên bản golf của chức năng mà bạn có thể đang tìm kiếm , sequence.
Ørjan Johansen

Vâng, đó là sự thật. Tôi chỉ nhìn vào (<*>)chữ ký của nó m (a → b) → m a → m b. Rất gần ...
hoàn toàn là

1
Cũng có thể Control.Lens.??, có thể đã được đề xuất đưa vào căn cứ tại một số điểm.
Ørjan Johansen

Tôi muốn trích xuất lặp đi lặp lại (.mapM id[fst,snd])như thế let r=(.mapM id[fst,snd]) in r(r.zipWith(+)), nhưng tôi đã không thể có được máy đánh chữ để chấp nhận một phiên bản miễn phí.
xnor

4

54 byte

Tôi thực sự nghi ngờ rằng chúng tôi sẽ đánh bại giải pháp 44 byte của @ H.PWiz, nhưng không ai sử dụng thực tế là (,)thực hiện lớp loại Functor, vì vậy đây là một giải pháp thú vị khác không quá tệ:

((<*>snd).((,).).(.fst).(+).fst<*>).flip(fmap.(+).snd)

Hãy thử trực tuyến!

Giải trình

Việc triển khai lớp loại Functorcho 2 -Tuples rất giống với lớp Either(từ cơ sở-4.10.1.0 ):

instance Functor ((,) a) where
    fmap f (x,y) = (x, f y)

instance Functor (Either a) where
    fmap _ (Left x) = Left x
    fmap f (Right y) = Right (f y)

Điều này có nghĩa gì cho thách thức này, là hàm sau thêm các phần tử thứ hai trong khi vẫn giữ phần tử đầu tiên của đối số thứ hai:

λ f = fmap.(+).snd :: Num a => (a, a) -> (a, a) -> (a, a)
λ f (1,-2) (3,-4)
(3,-6)

Vì vậy, nếu chúng ta có một số người trợ giúp nhỏ, helpPlz = \a b -> (fst a+fst b,snd b)chúng ta có thể làm (helpPlz<*>).flip(fmap.(+).snd)và sẽ được thực hiện. May mắn thay, chúng tôi có công cụ pointfreecung cấp cho chúng tôi:

helpPlz = (`ap` snd) . ((,) .) . (. fst) . (+) . fst

Vì vậy, chỉ cần cắm chức năng đó trở lại, chúng tôi đi đến giải pháp trên (lưu ý rằng (<*>) = apđó là trong cơ sở ).


4

60 byte

Tôi không thấy uncurrytình yêu nào ở đây, vì vậy tôi nghĩ rằng tôi đã tham gia và khắc phục điều đó.

uncurry$(uncurry.).flip(.)(flip(.).(+)).(flip(.).((,).).(+))

Tôi nghĩ rằng, với tất cả fstsnd, việc giải nén các đối số có uncurrythể mang lại một số kết quả. Rõ ràng, nó không hiệu quả như tôi mong đợi.


2
uncurrythật dài dòng :( Nhưng bạn có thể thay thế các dấu ngoặc đơn ngoài cùng bằng $.
Ørjan Johansen

Vâng, và thật không may, vấn đề với rất nhiều tên hàm trong Haskell. Chỉ quá lâu để chơi golf. Nhưng cảm ơn vì tiết kiệm 1 ký tự!
Silvio Mayolo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.