2017-04-08 15 views
3

함수형 프로그래밍에서 인수를 허용하는 함수를 호출하기위한 올바른 이름은 무엇입니까? 예를 들어 :빈 매개 변수가있는 함수를 호출하는 용어

// 2 types of execute functions 
type Function = 
    | UnitFunction of (unit -> unit) 
    | OperandFunction of (unit16 -> unit) 

let nop() = 
    () 

let shiftRegisterA operand = 
    registers.A <- registers.A <<< operand 

nopUnitFunction 호출 할 수 있으며, shiftRegisterAOperandFunction라고?

답변

9

여기서 말하는 것은 일반적으로 arity 기능입니다. 따라서 인수가없는 함수는 nullary 함수 및 단항 함수 - 단항 함수가있는 함수라고합니다.

F # 함수의 컨텍스트에서이 용어를 계속 사용할 수 있지만 보편적으로 이해할 수 있지만 완전히 정확하지는 않습니다. F # 함수는 항상 하나의 인수를 취하여 함수가 기본적으로 카레트 처리되므로 단일 값을 반환합니다.

nop의 경우 unit -> unit입니다. 즉, 유형이 unit (유형의 고독한 () 값) 인 단일 인수를 취해 unit 유형의 결과를 리턴합니다. 그것은 여전히 ​​그것을 단항 함수로 만듭니다.

2

어셈블리 프로그래밍에서 함수 호출은 스택의 매개 변수 (또는 호출 규칙에 따라 레지스터)를 누른 다음 함수의 주소로 점프하는 프로세스입니다.

Java, C#, C 등과 같은 고급 언어에서는이 프로세스가 다소 숨겨져 있습니다. 그러나 매개 변수가없는 함수, 즉 void을 호출 할 때 그 흔적을 볼 수 있습니다.

F #, haskell 등과 같은 함수형 프로그래밍 언어에서 함수 개념은 단일 입력으로부터 응답을 생성하는 수학 함수에 더 가깝습니다.

는 F 번호의 모든 기능을 하나의 입력의 다음과 같은 기능을 살펴 보자 동의 함을 확인하려면 :

// val f: (int*int) -> int 
let f (x,y) = x + y 

f 정수의 쌍을 받아 정수를 생성합니다. 쌍은 f의 관점에서 해답을 생성하기 위해 해체 된 단일 가치입니다.

// val g: int -> int -> int 
let g x y = x + y 

이 분명히 정수를 생산하는 두 개의 정수를 받아들이는 기능처럼 보이지만 우리가 그것을 다시 작성하는 경우 약간 우리가 반드시 사실이 아니다 참조 :

// val h: int -> int -> int 
let h x = fun y -> x + y 

h 여기 g하지만 동일합니다 우리는 h이 실제로 정수를 생성하는 정수를 허용하는 함수를 생성하는 단일 정수를 취하는 것을 봅니다.

서명에있는 ->은 올바른 연관성이 있으며 우리는 더 정확하게 괄호를 추가합니다. gh은 실제로 단일 입력을 취하고 있습니다. F 번호에 내 의견 기능에서

// val g: int -> (int -> int) 
let g x y = x + y 

// val h: int -> (int -> int) 
let h x = fun y -> x + y 

let gx = g 1 2 
let gy = (g 1) 2 
let hx = h 1 2 
let hy = (h 1) 2 

는 C#/Java 함수로 C#을/자바 말 함수보다 더 높은 수준의 추상화의있는 것은 F 번호 기능이 무엇보다 어셈블리 언어 기능을 개념적으로 가깝다.

또한 모든 함수가 단일 인수를 필요로하는 경우 인수를 허용하지 않는 함수에는 거의 의미가 없습니다.

하지만이 기능은 어떻습니까?

// val i: unit -> int 
let i() = 3 

3을 생성하는 인수가 허용되지 않습니까? 아니요, unit 유형의 값인 단위 값 ()을 허용합니다.

하스켈에서 그들은 void을 수락하고 대답 생산 기능의 이름이 있습니다

absurd :: Void -> a 

값은 아마 인수가없는 함수로 볼 수있다을하지만 난 범주 이론 전문가가 아니다.

예제 코드로 돌아 간다 :

type Function = 
| UnitFunction of (unit -> unit) 
| OperandFunction of (unit16 -> unit) 

기능적 접근 방식은 무언가를 같이 :

type Abstraction = 
| Concrete of obj 
| Function of Abstraction -> Abstraction 

Abstraction가 값 또는 기능 중 하나입니다.

어셈블리 언어와 비슷한 것으로 보이는 코드를 보면 매개 변수를 밀고 주소로 점프하는 것으로 함수를 생각하는 것이 좋습니다.

type Function = 
| VoidFunction of (unit -> unit) 
| UnaryFunction of (unit16 -> unit) 
| BinaryFunction of (unit16 -> unit16 -> unit) 

희망적입니다.

추신.

unit 유형은 작은 세부 사항이지만 IMO는 많은 좋은 것들을 가능하게합니다.

  • 진술 필요 없음.
  • 일반적인 프로그래밍을 간소화합니다 (void 경우에는 종종 특별한 경우가 필요합니다. Task<'T>Task).
  • 메모리의 주소로 점프하는 대신 수학 함수와 같은 기능을 생각할 수 있습니다.
+1

Re : 특수한 'void'의 경우, C#에서 가장 싫은 것은'Action'과'Func' 타입 사이의 구분입니다. – scrwtp