pointfree에 튜플 추가


16

함수를 표현할 수있는 가장 짧은 방법은 무엇입니까

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

포인트 프리 표기법으로?

pointfree.io 는 우리에게 제공

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

약간의 작업으로 단축 할 수 있습니다

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

76 바이트 그러나 이것은 여전히 보인다 정말 길고 복잡한 같은 간단한 작업. 더 짧은 point-free 함수로 pairwise add를 표현할 수있는 방법이 있습니까?

포인트 프리라는 의미로 분명히하기 위해, 포인트 프리 함수 선언은 기존 함수와 연산자를 가져 와서 원하는 함수가 생성되는 방식으로 서로 적용하는 것을 포함합니다. 역 따옴표, 괄호 리터럴 값 ( [], 0, [1..3], 등)은 허용하지만, 같은 키워드 있습니다 where와는 let없습니다. 이것은 다음을 의미합니다.

  • 변수 / 함수를 할당 할 수 없습니다

  • 람다를 사용할 수 없습니다

  • 수입하지 않을 수 있습니다

CMC 일 때의 동일한 질문입니다.


9
나는 그것이 실제로 포인트로 가득 차 있을 때 왜 "포인트 프리 ( point- free) " 라고 이해하지 못했습니다 . : P
Mr. Xcoder


5
우리가 최고의 Haskell 패키지 를 가져올 수 없다는 것은 부끄러운 일 (+)***(+)입니다. 그렇지 않으면 해결책이 될 것 입니다.
Silvio Mayolo

2
아이디어 : (+)<$>([1],2)<*>([3],4)제공합니다 ([1,3],6).
xnor

2
나는 xnor의 팁을 사용하여 훌륭한 솔루션을 만드는 데 시간을 보냈지 만 결국 이 쓰레기로 끝났습니다 . 내가 왜 가끔 시도하는지조차 모릅니다 ...
완전히 인간적인

답변:



8

44 바이트

Ørjan Johansen 덕분에 -8 바이트 Bruce Forte 덕분에 -3 바이트

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

온라인으로 사용해보십시오!

번역 :

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

67 바이트

Ørjan Johansen 덕분에 -8 바이트 Bruce Forte 덕분에 -1 바이트.

튜플 출력이 필요한 경우 :

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

온라인으로 사용해보십시오!

그렇습니다. 수동으로 익은 과일을 생산하지 않습니다. 그러나 나는 [a] → (a, a)회심에 만족합니다 .

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

이제 짧은 기능 이 있다면 m (a → b) → a → m b.


3
당신에게 그것을 나누는 것을 싫어하지만 mapM id[fst,snd]더 짧습니다.
Ørjan Johansen 2012

슬프게도, 당신이 찾고있는 기능 mapM id골프 버전입니다 sequence.
Ørjan Johansen

그래, 그건 사실이야. (<*>)의 서명을 보고 m (a → b) → m a → m b있습니다. 너무 가까이 ...
완전 인간

1
도 있는데 Control.Lens.??, 이는 수 있습니다 어떤 점에서 기본에 포함이 제안되었다.
Ørjan Johansen '12

(.mapM id[fst,snd])와 같이 반복적으로 추출하고 let r=(.mapM id[fst,snd]) in r(r.zipWith(+))싶지만 typechecker가 pointfree 버전을 수락하도록 할 수 없었습니다.
xnor

4

54 바이트

@ H.PWiz의 44 바이트 솔루션을 이길 것이라고 솔직히 의심하지만 아무도 (,)type 클래스 를 구현 한다는 사실을 사용하지 않았 Functor으므로 여기에 너무 나쁘지 않은 흥미로운 것이 있습니다.

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

온라인으로 사용해보십시오!

설명

유형 클래스의 구현 Functor을위한 2 -Tuples은 매우 유사하다 Either(에서 기본-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)

이것이이 도전에 의미하는 것은 다음 함수가 두 번째 인수의 첫 번째 요소를 유지하면서 두 번째 요소를 추가한다는 것입니다.

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

그래서 우리가 작은 조력자를 얻었을 때 우리는 helpPlz = \a b -> (fst a+fst b,snd b)할 수 (helpPlz<*>).flip(fmap.(+).snd)있고 할 수 있었습니다 . 운 좋게도 우리에게 다음과 같은 도구 pointfree를 제공합니다.

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

그래서 우리는 솔루션 위 (참고에 도착 단순히 그 기능 등을 연결하여 (<*>) = ap에있는 베이스 ).


4

60 바이트

나는 uncurry여기에 어떤 사랑도 보지 못해서 내가 튀어 나와서 고칠 것이라고 생각했다.

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

나는 모든 fstand snd와 함께 인수를 풀면 uncurry약간의 결과가 나올 수 있다고 생각했습니다 . 분명히, 내가 기대했던 것만 큼 유익하지 않았습니다.


2
uncurry너무 장황하다. :(하지만 당신과 가장 바깥 쪽 괄호를 대체 할 수 있습니다 $.
Ørjan 요한센에게

예, 불행히도 Haskell에 많은 함수 이름이 있습니다. 골프를하기에는 너무 길다. 그러나 1 문자 절약에 감사드립니다!
Silvio Mayolo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.