2009-10-01 3 views
9

F #의 unit system과 올바르게 상호 작용하는 방식으로 사용자 정의 제곱근 함수 (sqrt)를 작성하는 것이 가능한지 궁금했습니다.단위 안전 사각형 뿌리

이 같아야하는 것 :

 
let sqrt (x : float<'u^2>) = 
    let x' = x/1.0<'u^2> // Delete unit 
    (x ** 0.5) * 1.0<'u>  // Reassign unit 

그러나 이것은 인해 제로가 아닌 상수가 일반적인 단위을 가질 수되지 허용되지 않습니다.

이 함수를 작성하는 방법이 있습니까? sqrt이 내장되어 정상적으로 작동하므로 어떤 마법을 수행 할 수 있습니까?

+1

관련 질문 : (또한 답장이 @kvb) http://stackoverflow.com/questions/1398611/f-ununit-reunit-inside-a-function – Benjol

답변

6

0이 아닌 일반 상수를 허용하면 단위에 대한 유형 시스템의 안전을 매우 쉽게 상실 할 수 있습니다 (Andrew Kennedy의 papers 참조). 나는 당신의 마지막 질문에 대한 답은 정상적인 방법을 통해 그 타입 시그니처를 가진 파라 메트릭 함수를 정의하는 것이 가능해서는 안된다는 점에서 sqrt이 실제로 어떤 의미에서는 마술이라고 믿는다.

경우 :

let sqrt (x : float<'u^2>) = 
    let x' = (float x) ** 0.5 (* delete unit and calculate sqrt *) 
    ((box x') :?> float<'u>) 
6

@kvb 더 일반적으로 권리입니다 : 그러나, 는 (F #의 현재 버전 적어도) 권투와 캐스팅을 활용하여 당신이 원하는 것을 할 수 있습니다 당신은 단위가 아닌 알고있는 알고리즘을 가지고 있습니다 (예를 들어 여러분이 'cube root'라고 씁니다). 그리고 여러분은 그것들에 단위를두기를 원합니다. 올바른 타입의 서명을 가진 함수에서 알고리즘을 감쌀 수 있습니다. 유닛들이 들어올 때 유닛을 "버리거나"적절한 유닛을 나가기 위해 박스 앤드 다운 캐스트 (box-and-downcast) 접근법을 사용하기 위해 "떠 다니십시오 (float)".

RTM 릴리즈 (베타 2 이후)에서 F #에는 '백 유닛 추가'에 대한 기본 라이브러리 기능이 있습니다. 상자 및 다운 캐스팅 접근법은 현재 이러한 기본 요소의 부족을 극복하기위한 해킹 비트이기 때문에 언어/도서관.

+0

감사합니다 -이 새로운 라이브러리 함수 (Link)의 이름을 지으실 수 있습니까? – Dario

+3

이름은 아마도 예 : LanguagePrimitives 모듈의 "val inline FloatWithMeasure : float -> float <'u>" – Brian

+0

그리고 여기 있습니다 : http://msdn.microsoft.com/en-us/library/ee806527(VS.100).aspx – Benjol