F #에는 일반 T 유형의 산술 연산자를 직접 사용할 수없는 C#과 동일한 문제가 있습니까?F #에 일반 산술 지원 기능이 있습니까?
산술 연산을 지원하는 모든 값의 합계를 반환하는 일반 Sum 함수를 쓸 수 있습니까?
F #에는 일반 T 유형의 산술 연산자를 직접 사용할 수없는 C#과 동일한 문제가 있습니까?F #에 일반 산술 지원 기능이 있습니까?
산술 연산을 지원하는 모든 값의 합계를 반환하는 일반 Sum 함수를 쓸 수 있습니까?
F #에 대한 일부 제한된 지원이 있습니다. 일반적으로 CLR이나 F #에서 지원되지 않는 유형 클래스가 일반적으로 좋은 솔루션입니다.
F #은 '정적 멤버 제약 조건'및 '인라인'함수를 사용하는 산술 연산자를 오버로드했습니다. 이것은 예를 들어 +
연산자는 int
및 float
에 모두 작업 할 수 있습니다. 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
내가 알고있는 최고의 메커니즘 일반 제네릭은 형식 클래스이며, 슬프게도 C#, F # 또는 일반적인 .NET 런타임에서는 지원되지 않습니다. 그러나이 블로그 게시물에서 언급 한 바와 같이, 손으로 그들에게 자신을 시뮬레이션 할 수 있습니다 : 그 기술은 (익명 대표/람다를 사용하여) C# 2.0 이상에서 작동한다
Type Classes Are The Secret Sauce
. 해당 인터페이스의 인스턴스를 정의 할 수 있도록 INT와 같은 종류의 내장에 대한
종종 사람들은, 당신은 기존의 유형이 인터페이스를 구현 선언 할 수 없습니다
인터페이스는 모든 구현에서 해당 인터페이스의 모든 메소드가 동일한 '암시 적'매개 변수 유형을 사용한다고 선언합니다. Foo가 인터페이스를 구현한다면 분명히 'this'매개 변수는 그 구현을 위해 Foo 유형이어야합니다. 그러나 다른 메소드 매개 변수 도이 Foo 유형이어야한다는 요구가 없습니다.
Type classes 다른 매개 변수 중에서도 첫 번째 매개 변수뿐만 아니라 모든 메서드 매개 변수에 대해 이러한 종류의 제약 조건을 수행 할 수 있습니다.
앞에서 언급 한 것처럼 함수 테이블을 명시 적 인수로 전달하여 형식 클래스를 시뮬레이션 할 수 있습니다.
:
은 당신이 뭔가를 할 수 있습니다 (커뮤니티 위키는 여기에 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 '(+)'"
브라이언이 언급 한 바와 같이이, 거기 얻을 몇 가지 일반적인 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>
을 사용할 수 있다는 것을 의미한다고 믿습니다.
F #에서 정적 제약 조건을 사용할 때''a'' 대신'^ a'을 사용해야한다고 생각했지만 틀렸을 수도 있습니다 ... –
이 경우 두 가지 모두 작동합니다. – gradbot
이 특별한 경우에, 일반적인 매개 변수 나 제약 조건을 추론 할 수 있기 때문에 지정할 필요조차 없습니다 :'let inline sum a b = a + b' – kvb