[F#] 動的に数値型Interfaceを対応付けて関数を動かす
GetNumericAssociation なるもので動的に数値型Interfaceと対応付けられるみたい (http://cs.hubfs.net/forums/thread/3129.aspx) コード:#light open Math open Math.GlobalAssociations let Add (n1:'a) (n2:'a) = let tn : INumeric<'a> = GetNumericAssociation<'a>() tn.Add(n1, n2)結果は次のように色々な数値型で動作させることが可能Add 1 2 > val it : int = 3 Add 1. 2. > val it : float = 3.0 Add 1L 2L > val it : int64 = 3L Add 1.f 2.f > val it : float32 = 3.0fデフォルトで float, int32, int64, bigint, float32, Complex, bignum が使えて、 他の型も登録することで選択肢に加えることができるんだって。 Add を他の関数で使うとこれまた同じ効果を得られるlet MyGenFunc (n1:'a) (n2:'a) (n3:'a) = (Add (Add (Add n1 n2) (Add n1 n3)) (Add n2 n3))結果:MyGenFunc 1 2 3 > val it : int = 12 MyGenFunc 1. 2. 3. > val it : float = 12.0パフォーマンスを気にする場合は、ひとつの関数定義の中にすべてを含めてしまい、let MyGenFunc (n1:'a) (n2:'a) (n3:'a) = let tn : INumeric<'a> = GetNumericAssociation() let inline (+) (n1:'a) (n2:'a) = tn.Add(n1, n2) ((n1 + n2) + (n1 + n3) + (n2 + n3))演算子を適切に定義することで可読性を高めることもできる らしい! 他の例としてはこんなの(http://cs.hubfs.net/forums/thread/3823.aspx)let sumList (data:'a list) = // get the F# 'INumeric' interface implementation for a type 'a let num = GetNumericAssociation<'a>() data |> List.fold_left (fun a b -> num.Add(a,b)) num.Zero;; // sumList [1; 2; 3; 4; 5] ... returns 15 // sumList [1.1; 2.2; 3.3; 4.4; 5.5] ... returns 16.5Labels: F# FSharp
2 Comments:
重箱の隅をつつくようですが、「数字型」ではなく「数値型」でしょう。
コンピュータの世界では、数字と数値は別物ですから。
正確な表現で、検索に引っかかりやすくしていただけるとうれしいかなと。
By Anonymous, at 9:44 AM
まさに仰るとおりです(><b
修正しました
By BULE!, at 11:01 AM
Post a Comment
<< Home