2014-02-14 2 views
1

처음에는 함수 프로그래밍과 F #의 초보자 였으므로 이런 일을 할 수 있는지는 알 수 없습니다. 이 함수가 있다고 가정 해 봅시다 :F # 및 lisp와 같은 적용 함수

let sum x y z = x + y + z 

그리고 어떤 이유로 우리는 목록의 요소를 인수로 사용하여 호출하려고합니다. 내 첫 번째 시도는 다음과 같이 그냥 수행했습니다.

//Seq.fold (fun f arg -> f arg) sum [1;2;3] 

let rec apply f args = 
    match args with 
    | h::hs -> apply (f h) hs 
    | [] -> f 

... 컴파일되지 않습니다. 고정 유형 시스템을 사용하는 f의 유형을 판별하는 것은 불가능한 것처럼 보입니다.
하스켈에 identical question이 있고 유일한 솔루션은 유형 시스템을 능가하기 위해 Data.Dynamic을 사용합니다. 나는 F #에서 그것에 가장 가까운 아날로그가 Dynamitey이라고 생각하지만, 맞는 지 모르겠다. 이 코드

let dynsum = Dynamitey.Dynamic.Curry(sum, System.Nullable<int>(3)) 

는 또한 sum는 .NET의 위임하지 입력 objdynsum 변수를 생성하고,이 유형의 개체를 호출 할 수 없습니다.

질문 : 그렇다면 F #에서 해당 라이브러리를 사용하거나 사용하지 않고 어떻게 할 수 있습니까?

+0

예를 들어 해킹 없이는 할 수 없습니다. f 유형이 무한히 커집니다. 나는 이것의 어딘가에 중복이 있다고 확신한다. –

+0

이것은 닫기이다. https://stackoverflow.com/questions/7813472/why-wont-my-computer-let-me-greet-my-customers –

+0

@JohnPalmer 감사, 그것을 시험해 보겠다. 그러나 필자의 경우에는 [such] (http://stackoverflow.com/a/7813710/657390) 유형을 작성하는 방법이 명확하지 않다. – yuyoyuppe

답변

3

F #은 정적 형식의 함수형 언어이므로 F #에서 사용하는 프로그래밍 패턴은 LISP에서 사용하는 프로그래밍 패턴과 완전히 다릅니다 (실제로는 하스켈에서 사용하는 프로그래밍 패턴과도 다릅니다) . 따라서 여러분이 제안한 방식으로 함수로 작업하는 것은 일반적인 F # 프로그래밍에서 할 일이 아닙니다.

이 기능에 대한 몇 가지 시나리오가 있다면 원래의 문제에 대해 묻는 것이 좋습니다. 그러면 누군가가 관용적 인 F # 접근법을 찾는 데 도움이 될 것입니다.

즉, 권장하지는 않지만 강력한 .NET 리플렉션 기능을 사용하여 apply 함수를 구현할 수 있습니다. 느리고 안전하지 않지만 때때로 유용합니다.

open Microsoft.FSharp.Reflection 

let rec apply (f:obj) (args:obj list) = 
    let invokeFunc = 
    f.GetType().GetMethods() 
    |> Seq.find (fun m -> 
     m.Name = "Invoke" && 
     m.GetParameters().Length = args.Length) 
    invokeFunc.Invoke(f, Array.ofSeq args) 

이 코드는 함수의 런타임 유형을 찾고 Invoke 메서드를 찾고 호출합니다. 끝에

let sum x y z = x + y + z 
let res = apply sum [1;2;3] 
let resNum = int res 

, 당신이 정적으로 알려져 있지 때문에 int에 결과를 변환해야합니다.

+0

고마워, 그게 내가 찾고 있었던거야! :-) p.s. 나의 관심은 순전히 학문적이다. – yuyoyuppe