2010-08-24 4 views
16

이것은 매우 간단한 질문이며, 내가하고있는 일과 내가 F #을 어떻게 해석하고 있는지 확인하고 싶었습니다. 나는 문을 대신 함수로 printRandom을 만드는F # 함수 대 값

let printRandom = 
    x = MyApplication.getRandom() 
    printfn "%d" x 
    x 

이있는 경우, F #은 한 번 실행 한 다음에 값을 할당합니다. 이제는 printRandom을 호출 할 때 새로운 무작위 값을 얻고 인쇄하는 대신 처음으로 반환 된 값을 얻습니다. 나는이 문제를 얻을 수 있습니다 내 등을 정의 :

let printRandom() = 
    x = MyApplication.getRandom() 
    printfn "%d" x 
    x 

이 매개 변수가없는 함수와 값 사이의 차이를 그리는 적절한 방법인가를? 이것은 나에게 이상적인 것 같지 않습니다. 그것은 currying, 합성, 등등에있는 결과가 있는가?

+2

'x'의 첫 번째 발생 앞에'let'을 추가하고 싶다면 비교를 수행하고 그 결과를 버리는 것이 좋습니다. – kvb

+0

굉장한 질문, 똑같은 문제가있었습니다. 불행히도 나는 해결책을 발견 한 후에 이것을 발견했다. – ses011

답변

18

이 올바른 방법은 F #에 매개 변수없는 함수가 없다는 것입니다. 모든 함수는 매개 변수를 가져야하지만 때로는 그 함수가 무엇인지 신경 쓰지 않으므로 () (unit 유형의 싱글 톤 값)을 사용합니다.

let printRandom unused = 
    x = MyApplication.getRandom() 
    printfn "%d" x 
    x 

나이 :

let printRandom _ = 
    x = MyApplication.getRandom() 
    printfn "%d" x 
    x 

그러나 () 당신이 매개 변수를 사용하지 않는 것이 표현하는 기본 방법입니다 당신은 또한이 같은 기능을 만들 수 있습니다. 형식이 unit -> int이 아니기 때문에이 사실을 호출자에게 표시합니다 ('a -> int이 아님). 전화 사이트가 printRandom()이 아니기 때문에 독자에게뿐만 아니라 printRandom "unused"입니다.

실제로 currying 및 composition은 모든 함수가 하나의 매개 변수를 사용하여 하나의 값을 반환한다는 사실에 의존합니다.

그런데 단위로 호출을 작성하는 가장 일반적인 방법은 특히 Caml, SML 및 Haskell과 같은 F #의 .NET이 아닌 친척에서 공백을 사용하는 것입니다. ()은 싱글 톤 값이기 때문에 구문적인 것은 C#이 아니기 때문입니다.

8

귀하의 분석은 정확합니다.

첫 번째 인스턴스는 값이 아니라 함수를 정의합니다. 나는 F #으로 시작했을 때 이것이 몇 번 나에게 잡혔다는 것을 인정한다. C#에서 오면 다중 명령문을 포함하는 대입 표현식이 람다이므로 지연 평가를해야한다는 것은 매우 당연한 것처럼 보입니다.

이것은 F #의 경우가 아닙니다. 명령문은 거의 임의로 중첩 될 수 있습니다 (로컬로 범위가 지정된 함수 및 값을 갖는 경우). 이 기능에 익숙해지면 기능의 나머지 부분에서 액세스 할 수없는 기능 및 지속성을 만들 수 있으므로 이점으로 간주하기 시작합니다.

두 번째 방법은 논리적으로 인수를 취하지 않는 함수를 만드는 표준 방법입니다. F # 팀이이 선언을 위해 사용하는 정확한 용어를 모르겠다. (아마도 함수는 하나의 인자 인 unit을 취한다.) 그래서 나는 그것이 실제로 카레에 영향을 미칠지에 대해서는 언급 할 수 없다.

+4

함수에 'unit'유형의 매개 변수가 하나만 있기 때문에 currying이 실제로 적용되지 않습니다. 부분적인 애플리케이션은 이해할 수 없다. 함수를 완전히 적용하거나 (')을 건네거나, 전혀 호출하지 않는다. –

7

이 파라미터 이하 기능 값 간의 차이를 그리는 적절한 방법인가? 이것은 내게 이상적인 것보다 덜 것 같습니다. 그것은 카레, 합성, 결과가 있습니까 등?

예, 설명이 정확합니다.

그 가치가 무엇인지에 대해서는 선언에 함수를 부분적으로 평가할 수있는 매우 흥미로운 결과가 있습니다. 이 두 가지 기능을 비교 : contains2는 사람들이 매번 함수를 호출 설정 생성하는 반면

// val contains : string -> bool 
let contains = 
    let people = set ["Juliet"; "Joe"; "Bob"; "Jack"] 
    fun person -> people.Contains(person) 

// val contains2 : string -> bool 
let contains2 person = 
    let people = set ["Juliet"; "Joe"; "Bob"; "Jack"] 
    people.Contains(person) 

두 함수는 동일한 결과를 생성, contains는 선언에 설정된 사람을 만들고이를 다시 사용합니다. 최종 결과 : contains이 약간 빠릅니다. 따라서 여기에서 구별을 알고 있으면 더 빠른 코드를 작성할 수 있습니다.

3

기능 기관처럼 보이는 할당 기관은 몇 명의 프로그래머를 모르고 자했습니다. 당신은 할당 함수를 반환함으로써 훨씬 더 재미있는 일을 할 수 있습니다 :

let foo = 
    printfn "This runs at startup" 
    (fun() -> printfn "This runs every time you call foo()") 

난 그냥 http://blog.wezeku.com/2010/08/23/values-functions-and-a-bit-of-both/에서 그것에 대해 블로그에 글을 남긴 바있다.