2016-12-13 5 views
1

F # (및 Scala)에서 모험을 시작합니다. FunProg 사람들이 말하고자하는 주요 이점 중 하나는 타입 유추입니다. 스칼라에서 I는 다음과 같이 쓸 수 있습니다 :F # 대 스칼라 - 왜 F #에 물건의 종류를 말해야합니까?

val x = List(1,2,3) 
    x map ((x) => x+1) 

및 컴파일러는 x가 목록임을 알고 있으며, 이에 대한지도 기능지도의 변형을 사용하는 알고있다. 더 나아가지도 연산자가있는 객체 (list, array, Seq 등)에 상관없이 두 번째를 사용할 수 있습니다.

반면에 내가 본 모든 샘플에서 F 번호에 대해, 당신은 같은 것을 할 필요가 :

let x = [1;2;3];; 
x |> List.map(fun f -> f+1);; 

그래서 내가 알고 x의 종류가 무엇인지 정의하고 명시 적으로 사용할 필요를 List.map 저놈이 나에게 거의 의미가, 전체를 부정 "하지 않습니다 유형에 대한 걱정 "논쟁.

F #에 대해 뭔가 빠졌습니까? 이 작업을 수행하는 더 좋은 방법이 있습니까?

+4

'map'은 scala의 메소드이고'List.map'는 F #의'List' 모듈의 함수입니다. 사용할 수있는'map' 연산이 있다는 것을 알기 위해서도 여전히 두 경우 모두'x'의 타입을 알아야합니다. – Lee

+0

감사합니다. @Lee. 이 맵은 List에 대한 메소드이지만, 알려진 객체 (x는 List 타입 임)에 메소드를 적용 할 때, 직접 지정해야하는 이유는 무엇인가? . – Noam

+1

낄낄 거림 들어, 나는 FSI에서'열린'List를 시도했다. > stdin (5,6) : 오류 FS0892 :이 선언은 'RequireQualifiedAccess'로 표시된 'Microsoft.FSharp.Collections.List'모듈을 엽니 다. 모듈의 요소에 대한 한정 참조를 대신 사용하도록 코드를 조정하십시오 (예 : '지도'대신 'List.map'. 이렇게 변경하면 라이브러리에 새로운 구문이 추가 될 때 코드가 견고 해집니다. –

답변

6

유형 추론 제한 사항이 아닙니다. 문제는 F # core lib가 오버로드 메커니즘을 가진 일반 함수를 제공하지 않는다는 것입니다. 실제로 몇몇은, 일반적인 수 및 다른 재료를 위해 주로, 그러나 다만 약간있다.

해당 스타일로 F # 코드를 작성하려면 F#+을 살펴보십시오. 해당 라이브러리를 사용하면 다음과 같이 쓸 수 있습니다.

let x = [1;2;3];; 
x |> map (fun f -> f+1);; 

// val it : int list = [2; 3; 4] 

그러면 형식이 추측됩니다.

let y = Some 2 
x |> map (fun f -> f+1);; 

// val it : int option = Some 3 

정적 유형이 Map 인 모든 유형에서 작동합니다.

그래서 F # 형식 유추를 볼 수 있듯이 충분히 똑똑합니다. 함수가 모듈로 구성되기 때문입니다.

x |> _.map;; 

또는

x |> (.map);; 

하지만 그건 단지 인스턴스 멤버와 함께 일하는 것이 그것으로 작동하지 않을 것입니다 List.map에 대한 있도록 : 그 외에도 there is a proposal에서

것은 당신처럼 물건을 쓸 수 있도록 바로 지금입니다.

1

는 하드 코어 FPers에서 많은 사랑을하지 않지만이 실제로 F #에서 유창 라이브러리가있다, 당신은 그것을 nuget하고보다하면이 같은 것을 수행 할 수 있습니다

#if INTERACTIVE 
#r @"..\packages\FSharp.Core.Fluent-4.0.1.0.0.5\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\FSharp.Core.Fluent-4.0.dll" 
#endif 

let x = [1;2;3] 
x.map <| (+) 1 // ;-) 
//val it : int list = [2; 3; 4] 

그리고 물론 Linq를 확장 방법 또한 작동합니다 :