함수형 프로그래밍에서 "부분 함수"란 정확히 무엇을 의미합니까?


55

내 이해에 따르면 부분 함수는 예상보다 적은 수의 매개 변수를 함수에 전달하여 얻는 함수입니다. 예를 들어, 이것이 파이썬에서 직접 유효한 경우 :

>>> def add(x,y):
...    return x+y
... 
>>> new_function = add(1)
>>> new_function(2)
3

위의 스 니펫 new_function에서 부분 함수입니다. 그러나 Haskell Wiki 에 따르면 부분 함수의 정의는 다음과 같습니다.

부분 함수는 지정된 유형의 모든 가능한 인수에 대해 정의되지 않은 함수입니다.

제 질문은 "부분 기능"이 정확히 무엇을 의미합니까?


37
부분적으로 적용된 함수와 부분적인 함수를 혼동하고 있습니다.
— Willem Van Onsem

11
파이썬 partial은 부분 적용을 수행 하는 반면 하스켈은 자동으로 수행합니다. 위키 항목은 수학의 용어 인 부분 함수를 참조합니다 .
— L3viathan '10

9
엄밀히 말하면, Haskell은 부분 기능 적용을하지 않습니다. 모든 함수는 하나의 인수를 취하며 함수 애플리케이션은 함수를 단일 인수에 적용합니다. 무두질 을 시뮬레이션 당신이 처음에 여러 인수 기능을 시뮬레이션하여 다른 언어에 일부 응용 프로그램으로 생각하는 것이 무엇인지를. 같은 add 3 5기능은 단일 기능 응용 프로그램이 아닙니다. 이것은 add새로운 기능을 얻기 위해 3에 처음 적용됩니다. 그리고 나서 5에 적용됩니다.
— chepner

그리고 C #에서 partial메소드는 프로젝트 코드베이스의 다른 곳에서 선택적으로 구현 된 개인 메소드 의 전달 선언입니다 .
— Dai

1
귀하의 예는 유효 할 수 있습니다 :new_function = functools.partial(add, 1)
— wjandrea

답변:


76

당신은 두 가지 개념을 혼란스럽게 여기고 있습니다. 부분적 인가 함수 [하스켈 위키] A의 부분적인 기능 [하스켈 위키] .

부분적으로 적용되는 기능은 다음과 같습니다.

Haskell의 부분 적용 은 전체 인수보다 적은 수의 인수 를 여러 인수를 취하는 함수 에 전달 하는 것입니다.

반면 부분 함수는 실제로 총계가 아닌 함수입니다.

부분 함수는 지정된 유형의 모든 가능한 인수에 대해 정의되지 않은 함수입니다.


24
이것은 좋은 답변이지만 답변 자체에 부분 함수의 예를 추가하여 향상시킬 수 있습니다.
— ApproachingDarknessFish

2
부분적으로 적용된 함수의 정확한 정의에 동의하지 않습니다. Haskell의 함수는 항상 하나의 인수 만 사용하고 "여러 인수"는 사용하지 않습니다. "하스켈에서 부분적 적용 (부분적으로 기능 적용)은 다른 인수에 더 이상 적용 할 수없는 값을 얻는 데 필요한 전체 수보다 적은 수의 인수를 제공하는 것과 관련이 있습니다." ( 여기 에서 수정 됨 )
— TerryA

21

부분 함수 (함수 프로그래밍과 수학의 맥락에서)는 위키가 말하는 것입니다. 가능한 모든 인수에 대해 정의되지 않은 함수입니다. 프로그래밍의 맥락에서, 우리는 일반적으로 "정의되지 않음"을 정의되지 않은 행동, 예외 또는 비 종료를 포함한 여러 가지 중 하나로 해석합니다.

부분 함수의 예는 정수 나누기입니다. 제수가 0이면 정의되지 않습니다 (Haskell에서 오류가 발생 함).

위의 스 니펫에서 new_function은 부분 함수입니다.

이 코드는 Python에서 단순히 오류를 유발하지만 의도 한대로 작동하면 전체 (부분이 아님) 함수가됩니다.

주석가가 이미 지적했듯이, 부분적으로 적용되는 기능 이라는 사실을 생각하고있을 것 입니다.


18

대답은 모두 설명합니다. 각 언어로 하나의 예를 추가하겠습니다.

def add(x,y):
    return x+y

f = add(1)
print(f(3))

    f = add(1)
TypeError: add() missing 1 required positional argument: 'y'

이것은 부분 함수도 아니고 카레 함수도 아니며, 모든 인수 를 주지 않은 함수일뿐 입니다.

파이썬에서 커리 된 함수는 다음과 같아야합니다.

partialAdd= lambda x: lambda y: x + y

plusOne = partialAdd(1)
print(plusOne(3))

4

그리고 haskell에서 :

plus :: Int -> Int -> Int
plus x y = x + y

plusOne = plus 1

plusOne 4

5

파이썬의 부분 함수 :

def first(ls):
    return ls[0]

print(first([2,4,5]))
print(first([]))

산출

2

print(first([]))
  File "main.py", line 2, in first
    return ls[0]
IndexError: list index out of range

그리고 Haskell에서 귀하의 링크가 나타났습니다 :

head [1,2,3]
3

head []
*** Exception: Prelude.head: empty list

총 함수 란 무엇입니까?

글쎄, 기본적으로 반대입니다 : 이것은 해당 유형의 모든 입력에 작동하는 함수입니다. 다음은 파이썬의 예입니다.

def addElem(xs, x):
  xs.append(x)
  return xs

약간의 트릭을 사용하면 무한 목록에서도 작동합니다.

def infiniList():
    count = 0
    ls = []
    while True:
        yield ls
        count += 1
        ls.append(count)

ls = infiniList()
for i in range(5):
  rs = next(ls)

print(rs, addElem(rs,6))

[1, 2, 3, 4]
[1, 2, 3, 4, 5] [1, 2, 3, 4, 5]

그리고 Haskell의 동등한 것 :

addElem :: a -> [a] -> [a]
addElem x xs = x : xs

addElem 3 (take 10 [1..])
=> [3,1,2,3,4,5,6,7,8,9,10]

여기서 함수는 영원히 멈추지 않습니다. 개념은 동일합니다. 모든 목록에 대해 기능이 작동합니다.


파이썬은 표준 라이브러리에서 부분 함수 를 지원한다고 언급 할 가치가 있습니다.
— Monica Monica
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.