카레 좀 만들어 줘


20

인수 x 1 , x 2 ,…, x n 을 취하는 함수 f가 있음

                                               – 즉.  f : X 1 × X 2 ×… × X n → Y

카레는 f 를 하나의 인수 a 1 을 취하는 함수로 재정의 합니다. 이 기술은 예를 들어 pow우리가 작성할 수 있는 카레 함수 와 같은 부분 적용에 유용합니다 exp = pow(e).

다음 함수 f 가 세 개의 인수 ( f : X 1 × X 2 × X 3 → Y )를 취하는 것으로 가정합니다 .

def f(a,b,c):
  return a + b * c

이 함수를 커리하면 f_curry : X 1 → (X 2 → (X 3 → Y))남습니다. 이제이 함수를 두 번 호출 하면 다음과 같은 f_curry(1)(2)함수 ( h)를 얻게됩니다 .

def h(c):
   return 1 + 2 * c

커리 함수 f는 다음과 같이 작성할 수 있습니다 (Python 3).

def f_curry(a):
  def g_curry(b):
    def h(c):
      return a + b * c
    return h
  return g_curry

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

도전

당신의 도전은 위에서 설명한대로 기능을 카레하는 것입니다, 여기에 규칙이 있습니다 :

  • 입력은 최소한 2 개의 인수를 취하는 블랙 박스 함수 입니다.
  • 입력 함수는 항상 고정 된 수의 인수를 갖습니다 (주와는 달리 printf, 참고 : 인수가 ≥2 인 함수를 지원해야 함)
  • 언어에서 기본적으로 카레 함수를 사용하는 경우 (예 : Haskell) "고차 함수"대신 입력 함수가 N- 튜플을 통해 정의 될 수 있습니다.
  • 인수의 수를 입력으로 사용할 수 있습니다
  • 출력은 입력의 카레에 상응하는 값이됩니다 *
  • 출력 기능은 다음과 같습니다.
    • 입력 함수가 취하는 인수의 수와 같거나 적다
    • 올바른 유형의 인수와 함께 호출

* 이것은 인수가 있는 입력 f과 모든 유효한 인수에 대한 N출력을 h의미 a1,…,aN합니다 f(a1,a2,…,aN) == h(a1)(a2)…(aN).



입력이 def f(a,b,c): return a + b * c있고 출력이 def f_curry(a): def g_curry(b): def h(c): return a + b * c return h return g_curry?
DanielIndie

@DanielIndie :이 예제를 사용하는 경우 입력은 f(어딘가에 정의되어 있음) 출력 은와 같습니다 f_curry. 또는 입력은 lambda a,b,c: a+b*c이고 출력은에 해당하는 함수 f_curry입니다.
ბიმო

가장 정적으로 유형이 지정 된 언어에서는 수행하기가 어렵습니다 ...이 유형 기능이 필요하다고 생각합니다.
Paŭlo Ebermann

@ PaŭloEbermann : 사실, 일부 언어는이 작업을 해결할 수 없습니다 (태그 기능 프로그래밍 참조 ). 그러나 정적으로 유형이 지정된 일부 언어는 유효한 I / O가 될 함수 포인터를 사용할 수 있습니다. 이것이 주로 인수의 수를 추가 입력으로 허용하는 이유입니다.
ბიმო

답변:


11

자바 스크립트 (ES6), 35 바이트

f=g=>g.length<2?g:a=>f(g.bind(f,a))

9

이드 , 204 바이트

import Data.HVect
C:(a:Vect n Type)->(HVect a->Type)->Type
C[]T=T[]
C(h::t)T=(x:h)->C t(T .(x::))
c:{a:Vect n Type}->{T:HVect a->Type}->((b:HVect a)->T b)->C a T
c{a=[]}f=f[]
c{a=h::t}f=\v=>c(\u=>f(v::u))

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

종속 유형에 대한 작업처럼 들립니다! 아마도 요


C 는 카레 링 기능입니다. a = [t 1 , t 2 ,… t n ] 유형의 벡터 와 유형 함수 T : HVect a → Type이 주어지면 새로운 유형을 반환합니다.

           (x 1  : t 1 ) → (x 2  : t 2 ) →… → (T [x 1 , x 2 ,… x n ])

여기서 HVect 는 Idris Prelude 의 이기종 벡터 유형 입니다.이 유형의 요소는 n- 튜플입니다. n 개의 다른 유형 n .

C를 취하는 함수이다 및 T를 암시 적 인수로서, 다음 변환 uncurried 함수 타입 (HVect a) → T (B) (B)를 (A) 내로 카레 타입 중 하나 C T 자 .f

( C는 단순히 우리가하고 싶은 일을 설명합니다 .c는 실제로 그것을 수행합니다. 그러나 Idris는 모든 최상위 정의에 유형 서명이 필요하기 때문에 C를 정의하지 않으면 벗어날 수 없습니다 .)


TIO 링크는 사용 예를 제공합니다. 다음과 같이 3- 튜플 (Nat, Nat, String) 에 함수를 정의하면 :

uncurried : HVect [Nat, Nat, String] -> String
uncurried [a, b, c] = show (a*a + b*b) ++ c

그런 uncurried [3, 4, "th"]다음와 같은 결과 를 얻습니다 c uncurried 3 4 "th". 이드리스는 인수를 추론 a=[Nat, Nat, String]하고 T=const String우리를 위해, 저는 믿습니다.

나는이 코드를 timjb의 요점 을 기반 으로했습니다.


제 생각에는 Haskell과 Idris의 튜플은 실제로 HVect기본적 HVect으로 있어야합니다. 본질적으로 당신이 논쟁 할 수없는 튜플입니다.
Esolanging 과일


5

R , 96 바이트

y=function(f,n=length(formals(f)),p=list())function(x,u=c(p,x))`if`(n<2,do.call(f,u),y(f,n-1,u))

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


이전 버전 (97 바이트)

@JayCE 덕분에 -1 바이트


근본적으로 단축시키는 방법을 모르겠습니다 . 첫 번째 줄의 끝에서 중괄호와 공백을 제거하여 3 바이트를 버릴 수 있습니다. 그리고 바이트 수에 함수 이름을 포함시키지 않는다는 관례로 인해 두 가지가 더 있습니다. TIO
ngm

@ngm 함수 이름은 재귀적일 때 포함되어야합니다.
Ørjan Johansen 님

@ngm : 나는 :) 바이트의 10 분 절약 하위 기능 안에 if 문 넣어
digEmAll을


3

파이썬 2 , 60 바이트

c=lambda f,n,l=[]:lambda a:n-1and c(f,n-1,l+[a])or f(*l+[a])

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

바닥 글은 줄당 다음과 같은 방식으로 STDIN을 사용하는 테스터입니다.

  1. 기능 자체
  2. 함수 인수의 개수, ≥2
  3. 인수 목록 ( [a,b,...])

인수 목록은 테스터에 입력으로 제공되지만 실제로는 카레에 해당하는 항목이 목록 앞에 추가되고 함수 호출에 의해 목록이 줄어 듭니다.

비슷한 55 바이트 버전이 ovs 에 의해 친절하게 제공되었습니다 .

c=lambda f,n,*l:lambda a:n-1and c(f,n-1,*l,a)or f(*l,a)

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





1

첨부 , 5 바이트

Curry

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

단순 내장, 크게 흥미롭지 않은. 그러나 처음부터 다음 버전이 있습니다.

첨부, 35 바이트

{If[#__2<#_,Fold[`&:,$'__],_@@__2]}

설명:

{If[#__2<#_,Fold[`&:,$'__],_@@__2]}
{                                 }    lambda
 If[       ,              ,      ]     if
    #__2                                 the number of parameters after the first
        <#_                              is less than the arity of the first
            Fold[   ,    ]             then fold:
                 `&:                     right-function bonding
                     $                     over this function
                      '__                  paired with the rest of the parameters
                          ,            otherwise:
                           _@@           call the first parameter
                              __2        with the rest of them

1

자바 8, 46 + 318 = 364 바이트

이것은 함수와 인수 수를 취하고 커리 된 함수를 반환하는 카레 (ha) 람다입니다.

import java.lang.reflect.*;import java.util.*;

f->p->new java.util.function.Function(){Object F=f;Method m=F.getClass().getDeclaredMethods()[0];int P=p;List a=new Stack();public Object apply(Object r){a.add(r);try{return a.size()<P?this:m.invoke(F,a.toArray());}catch(Throwable t){t=t.getCause();if(t instanceof Error)throw(Error)t;else throw(RuntimeException)t;}}}

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

제출 유형

입력 기능

함수 입력은 함수를 나타내는 단일 메소드 (상속 된 메소드 제외)가있는 오브젝트입니다. (예) 3 개의 매개 변수 기능을 지원해야하므로 표준 기능 인터페이스를 입력 유형으로 사용할 수 없습니다. 또한 표준 java.util.function.Function과 같은 형식으로 캐스팅 된 람다식이 전달 될 수 있습니다 (단일 방법은 apply).

점검 된 예외는 입력 함수에서 선언 될 수 있지만, 예외는 발생하지 않을 수 있습니다 (예 : 출력 함수의 호출자에게 전파되지 않음). Java 기능 인터페이스가 확인 된 예외를 허용하지 않기 때문에 수용 가능한 것으로 추정됩니다 (전파를 전달하면 제출이을 리턴하지 못하게됩니다 Function). 런타임 예외 (RuntimeException또는에Error 가 전파됩니다.

출력 기능

제출 결과는입니다 java.util.function.Function<Object, Object>. 메서드 Object와 함께 평문 을 반환하는 것을 고려 apply했지만 (입력에서와 같이) 결과를 호출하기 위해 리플렉션이 필요합니다. 표현.

용법

제출은 함수를 반환하기 때문에 ObjectObject(로, 출력이 직접 호출 할 수 있습니다apply ) 만, 후속 중간 리턴 값은 해당 유형 (예를 들면 캐스팅해야 java.util.function.Function<Object, Object>호출되기 전에). 사용 예는 TIO에 문의하십시오.

Java 함수 (예 : 메소드)는 일류 객체가 아닙니다. 따라서 챌린지 설명의 출력 글 머리 기호에 사용 된 구문은 Java에서 의미가 없습니다. 보다는 f(a1, a2, a3)우리가 f.apply(a1, a2, a3), 그리고보다는 f(a1)(a2)(a3)우리가f.apply(a1).apply(a2).apply(a3) .

한계

중간 결과가 적용되면 (인수 추가) 결과는 실제로 원래 결과의 변형 된 사본입니다. 예를 들어,이 스 니펫에서 :

Function<Object, Function<Integer, Function>> submission = ...;
Function c = submission.apply((IntBinaryOperator) (a, b) -> a + b).apply(2);
Function c2 = (Function) c.apply(2);
System.out.println(c2.apply(2));
System.out.println(c2.apply(3));

라인 4는 인쇄 것 4,하지만 시간이 있기 때문에 5 행은 실패 c2이미 인수 보유 2하고 2도 그 (참고c2 == c ). 이것은 카레 정신을 위반하지만 도전에 명시된 특정 요구 사항을 충족합니다.

언 골프

ungolfed 사본은 TIO를 참조하십시오.



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.