2017-02-21 18 views
2

一般的な列挙型の値をとり、その基礎となる整数値を2倍にするF#関数を記述したいと思います。幸い、intという組み込み関数があります。この関数は、列挙型を整数に変換するので、これは簡単に行えますか?ここに私の最初の試みだ:Enum型のF#型制約

let doubler (value : 't when 't : enum<int>) = 
    2 * (int value) 

悲しいことに、これは次のコンパイラメッセージで結果:

Program.fs(2,10):警告FS0064:この構築物は、コードがより 少なく、一般的なことになり型の注釈で示されます。タイプ変数 'はタイプ' int 'に制約されています。

Program.fs(2,10):エラーFS0071: 型の推論変数にデフォルトの型 'int'を適用すると、型の制約が一致しません。タイプ 'int' はCLI enumタイプではありません。 Program.fs(1,28) - (1,42)も参照してください。 さらに型の制約を加えることを検討してください。

私は間違っていますか? F#の包括的な列挙型の値から根底にある整数を抽出する良い方法はありますか?

+0

'enum'は、値をその表現に変換します。コンパイラはあなたのために制約を入れます。下記参照。 – s952163

答えて

1

EnumToValueが必要です。

open FSharp.Core.LanguagePrimitives 

let doubler xEnum = 
     2 * EnumToValue(xEnum) 

type ColorEnum =  
      | Red=0 
      | Yellow=1 
      | Blue=2 

let blue = ColorEnum.Blue 

doubler blue 
//val it : int = 4 

そして、あなたはdoublerの型シグネチャを調べる場合:

ヴァル・ダブラー:xEnum: ' - > int型':あなたの最初のエラーについて列挙

intは特別な意味を持ち、それも機能です。あなたが指摘するように、あなたが列挙型で基本となる型の制約を使用しますが、その場合にはタイプについて明確にするため、混乱はありませんすることができます

let double2 (x:'T when 'T:enum<int32>) = 
    2 * EnumToValue(x) 

残念ながら、あなたはまだintにキャストすることはできませんEnumToValueを使用しないでください。コンパイラの問題などが考えられます。おそらく、EnumToValueの内部がヒントを与えることができますか?

+0

それは完璧に見える、ありがとう。しかし、私のコードがうまくいかないというのは奇妙に思えます。 – brianberns

+0

@brianbernsそれは一般的なEnum(私は思う)がないからです。あなたが制約したいなら、 'let doubl2(x: 'T when' T:enum )='と言う必要があります。これは、xがEnumの1つの型にすぎないように制約します。そして、あなたはまだ 'int'問題にぶつかります。私はその根本的な原因を知らない。 – s952163

+0

私の言うことは、 'enum 'のようなものはないということです。もちろん、型シグネチャを盗み出して明示的に指定することもできます: 'let tripler(xEnum: 'a when:a:enum <_>)= 3 * EnumToValue(xEnum)'。しかし、それがなくても、コンパイラは例えばchar列挙型のエラーを返します。正直なところ、F#で列挙型を使用する必要はありませんでした.DUがあるため、おそらくコマンドライン引数を除いています。 – s952163

関連する問題