Chuyển đổi điểm miễn phí sang điểm nhấn


9

Là một hacker Haskell, tôi thích ký hiệu không có điểm hơn là có điểm. Thật không may, một số người thấy ký hiệu không có điểm khó đọc và tôi thấy khó có được số ngoặc đơn chính xác khi tôi viết một cách chính xác. Giúp tôi chuyển đổi mã được viết bằng pointfree sang ký hiệu nhọn!

Trong khoảng

Trong ký hiệu không có điểm, chúng tôi sử dụng các điểm (có, thực sự) để cung cấp đầu ra của hàm này sang hàm khác. Giả sử, nếu bạn có một hàm succlấy một số và thêm 1 vào nó, và bạn muốn tạo một hàm thêm 3 vào một số, thay vì làm điều này:

\x -> succ(succ(succ(x)))

bạn có thể làm điều này:

succ.succ.succ

Tuy nhiên, Pointfree chỉ hoạt động với các hàm có một tham số duy nhất (dù sao trong thử thách này), vì vậy nếu chức năng của chúng tôi không succphải là addlấy 2 số và cộng chúng lại với nhau, chúng tôi sẽ phải cung cấp cho nó các đối số cho đến khi chỉ còn lại một:

pointful:  \x -> add 1(add 1(add 1 x)) 
pointfree: add 1 . add 1 . add 1

Cuối cùng, các hàm có thể lấy các hàm khác làm đối số:

Pointfree: map (f a . f b) . id
Pointful:  \x -> map (\x -> f a (f b x)) (id x)

Javascript equivalent: x => map (x => f(a,f(b,x)), id(x))

Đầu vào và đầu ra dự kiến

f . f . f
\x -> f (f (f x))

f a . f b . f c
\x -> f a (f b (f c x))

f (f a . f b) . f c
\x -> f (\x -> f a (f b x)) (f c x)

a b c . d e . f g h i . j k l . m
\x -> a b c (d e (f g h i (j k l (m x))))

a.b(c.d)e.f g(h)(i j.k).l(m(n.o).p)
\x->a(b(\y->c(d y))e(f g h(\z->i j(k z))(l(\q->m(\w->n(o w))(p q))x)))

Quy tắc

  • Đầu ra của bạn có thể có nhiều khoảng trắng hoặc dấu ngoặc đơn hơn mức yêu cầu, miễn là chúng được cân bằng
  • Bạn không phải đảm bảo rằng tên của biến bạn tạo \xkhông được sử dụng ở nơi nào khác trong mã
  • Lựa chọn của bạn là tạo một chức năng hay một chương trình đầy đủ
  • Đây là codegolf, mã ngắn nhất trong byte giành chiến thắng!

Bạn có thể thấy cùn hữu ích, nó chuyển đổi giữa hai ký hiệu (nhưng cũng có thể xác định mã khi có thể): https://blunt.herokuapp.com


15
Trong ký hiệu không có điểm, chúng tôi sử dụng các điểm để cung cấp đầu ra của một chức năng cho một chức năng khác Đó rõ ràng là một nỗ lực để chứng minh rằng không có điểm là vô nghĩa
Luis Mendo

1
"Pointfree chỉ hoạt động với các chức năng có một tham số duy nhất". Điều đó không đúng: (+).(*3)giống như\x y->3*x+y
Damien

2
@Damien Tôi đã cố gắng để làm cho thử thách dễ tiếp cận hơn. Bạn cũng có thể làm những việc như con cú: (.).(.)chuyển đổi thành\i b c f -> i (b c f)
BlackCap

2
Vì vậy, để rõ ràng cho những người không biết cú pháp của Haskell: trước tiên chúng ta nên khớp dấu ngoặc đơn trong đầu vào và lặp lại trên mỗi biểu thức được ngoặc đơn cấp cao nhất; và sau đó thay thế .bằng một (, thêm một \xvà nối một tương ứng xvà nhiều )như được yêu cầu? Hay nó phức tạp hơn thế?
Peter Taylor

1
@Linus \ d->f(\k->f(f d k)), nhưng bạn có thể giả sử rằng tất cả các dấu chấm được cung cấp hai đối số trong thử thách này
BlackCap

Câu trả lời:


4

Haskell, 163 142 133 byte

p(x:r)|[a,b]<-p r=case[x]of"("->["(\\x->"++a++p b!!0,""];"."->['(':a++")",b];")"->[" x)",r];_->[x:a,b]
p r=[r,r]
f s=p('(':s++")")!!0

Hãy thử nó trên Ideone.

Ung dung:

p('(':r)|(a,b)<-p r = ("(\\x->"++a++(fst(p b)),"")
p('.':r)|(a,b)<-p r = ('(':a++")",              b)
p(')':r)            = (" x)",                   r)
p(x  :r)|(a,b)<-p r = (x:a,                     b)
p _                 = ("",                     "")

f s=fst(p('(':s++")"))

2

Haskell, 402 289 byte

Khá lâu, nhưng tôi nghĩ rằng nó hoạt động ..

(!)=elem
n%'('=n+1
n%')'=n-1
n%_=n
a?n=a!"."&&n<1
a#n=a!" ("&&n<1||a!")"&&n<2
q a='(':a++")"
p s o n[]=[s]
p s o n(a:b)|o a n=[t|t@(q:r)<-s:p""o(n%a)b]|0<1=p(s++[a])o(n%a)b
k=foldr((++).(++" ").f)"".p""(#)0
f t|not$any(!"(. ")t=t|l@(x:r)<-p""(?)0t=q$"\\x->"++foldr((.q).(++).k)"x"l|0<1=k t
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.