2010-02-09 1 views

답변

4

F #에 대한 일부 제한된 지원이 있습니다. 일반적으로 CLR이나 F #에서 지원되지 않는 유형 클래스가 일반적으로 좋은 솔루션입니다.

F #은 '정적 멤버 제약 조건'및 '인라인'함수를 사용하는 산술 연산자를 오버로드했습니다. 이것은 예를 들어 + 연산자는 intfloat에 모두 작업 할 수 있습니다. inline 함수를 작성하여 내장 수학 연산자를 기반으로 구현하고 진행을 진행할 수 있지만 일반적으로 수행하는 것은 간단합니다. 예를 들어 체크 아웃 할 수 있습니다. 소스 코드는 Array.sum (FSharp.Core의 array.fs에 ​​있음)로 CTP와 함께 제공되는 F # 소스 배포판에서 느낌을 얻습니다.

참조 또한 '정적 멤버 제약'이 해답의 일부가 '형의 클래스 시뮬레이션'

http://msdn.microsoft.com/en-us/library/ee370581(VS.100).aspx

같은

Functions with generic parameter types

뿐만 아니라 도서관의 다양한 비트를 http://msdn.microsoft.com/en-us/library/ee340262(VS.100).aspx

2

내가 알고있는 최고의 메커니즘 일반 제네릭은 형식 클래스이며, 슬프게도 C#, F # 또는 일반적인 .NET 런타임에서는 지원되지 않습니다. 그러나이 블로그 게시물에서 언급 한 바와 같이, 손으로 그들에게 자신을 시뮬레이션 할 수 있습니다 : 그 기술은 (익명 대표/람다를 사용하여) C# 2.0 이상에서 작동한다

Type Classes Are The Secret Sauce

. 해당 인터페이스의 인스턴스를 정의 할 수 있도록 INT와 같은 종류의 내장에 대한

종종 사람들은, 당신은 기존의 유형이 인터페이스를 구현 선언 할 수 없습니다

  1. 몇 가지 문제로 인터페이스를 설정하지만, 실행 .
  2. 인터페이스는 다른 인수의 형식을 메서드로 제한 할 수 없습니다.

인터페이스는 모든 구현에서 해당 인터페이스의 모든 메소드가 동일한 '암시 적'매개 변수 유형을 사용한다고 선언합니다. Foo가 인터페이스를 구현한다면 분명히 'this'매개 변수는 그 구현을 위해 Foo 유형이어야합니다. 그러나 다른 메소드 매개 변수 이 Foo 유형이어야한다는 요구가 없습니다.

Type classes 다른 매개 변수 중에서도 첫 번째 매개 변수뿐만 아니라 모든 메서드 매개 변수에 대해 이러한 종류의 제약 조건을 수행 할 수 있습니다.

앞에서 언급 한 것처럼 함수 테이블을 명시 적 인수로 전달하여 형식 클래스를 시뮬레이션 할 수 있습니다.

:

4

은 당신이 뭔가를 할 수 있습니다 (커뮤니티 위키는 여기에 C 번호로 변환 그 기사에서 예를 게시하지만, 장황한 explaination과 시간의 부족 것이다). 내가 let result = sum 3 4을 시도하는 경우

let inline sum<'a when 'a : (static member (+) : 'a -> 'a -> 'a)> a b = 
    a + b 

let result = sum<int> 3 4 

그러나 나는 오류를 "type ambiguity inherent in the use of the operator '(+)'"

+2

F #에서 정적 제약 조건을 사용할 때''a'' 대신'^ a'을 사용해야한다고 생각했지만 틀렸을 수도 있습니다 ... –

+0

이 경우 두 가지 모두 작동합니다. – gradbot

+5

이 특별한 경우에, 일반적인 매개 변수 나 제약 조건을 추론 할 수 있기 때문에 지정할 필요조차 없습니다 :'let inline sum a b = a + b' – kvb

8

브라이언이 언급 한 바와 같이이, 거기 얻을 몇 가지 일반적인 arithmethic에 대한 지원 내장 당신은 당신이 몇 가지 일반적인를 정의 할 수 있도록 '정적 제약'을 사용할 수 있습니다 이 기능은 다소 제한적이지만 직접 기능합니다.

이 외에도 함수에서 사용할 때 좀 더 느린 동적 '숫자 연관'을 사용할 수도 있지만 예를 들어 고유 한 벡터 또는 행렬 유형을 정의하는 데 유용하게 사용할 수 있습니다. 다음은 예제입니다.

#r "FSharp.PowerPack.dll" 
open Microsoft.FSharp.Math 

let twoTimesLarger (n:'a) (m:'a) = 
    let ops = GlobalAssociations.GetNumericAssociation<'a>() 
    let sel = if ops.Compare(n, m) > 0 then n else m 
    ops.Multiply(sel, ops.Add(ops.One, ops.One)) 

먼저 기능을 포함하는 F # PowerPack 라이브러리를 참조해야합니다. 그런 다음 서명이 'a -> 'a -> 'a 인 제네릭 함수를 정의합니다. 첫 번째 행은 'a 유형의 작업에 대해 동적으로 숫자 작업을 가져옵니다 (기본적으로 유형을 키로 사용하는 조회 테이블을 사용합니다). 그런 다음 숫자 연산 객체의 메서드를 사용하여 곱셈, 덧셈 (Multiply, Add) 및 기타 여러 가지 작업을 수행 할 수 있습니다. 이 함수는 숫자와 함께 작동합니다 : 당신이 당신의 자신의 숫자 형식을 정의 할 때

twoTimesLarger 3 4 
twoTimesLarger 2.3 2.4 
twoTimesLarger "a" "b" // Throws an exception! 

, 당신은 수치 연산을 정의하고 GlobalAssociations.RegisterNumericAssociation를 사용하여 등록 할 수 있습니다. 나는 이것이 당신이 작업을 등록한 후에 내장 된 F # Matrix<YourType>Vector<YourType>을 사용할 수 있다는 것을 의미한다고 믿습니다.