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


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.