「プログラミング F# 3.0」を読んでいるときに、このコードに出くわしました。
type BitCounter =
static member CountBits (x : int16) =
let mutable x' = x
let mutable numBits = 0
for i = 0 to 15 do
numBits <- numBits + int (x' &&& 1s)
x' <- x' >>> 1
numBits
static member CountBits (x : int) =
let mutable x' = x
let mutable numBits = 0
for i = 0 to 31 do
numBits <- numBits + int (x' &&& 1)
x' <- x' >>> 1
numBits
static member CountBits (x : int64) =
let mutable x' = x
let mutable numBits = 0
for i = 0 to 63 do
numBits <- numBits + int (x' &&& 1L)
x' <- x' >>> 1
numBits
補助機能を作成して、この部分を短縮しようとしました。
type BitCounter =
static member CountBitsWithRangedMask x upBound typeConverter =
seq { for i = 0 to upBound do yield 1 <<< i }
|> Seq.map typeConverter
|> Seq.map ((&&&) x)
|> Seq.filter ((<>) (typeConverter 0))
|> Seq.length
static member CountBits (x : int16) =
BitCounter.CountBitsWithRangedMask x 15 int16
static member CountBits (x : int) =
BitCounter.CountBitsWithRangedMask x 31 int
static member CountBits (x : int64) =
BitCounter.CountBitsWithRangedMask x 63 int64
しかしstatic member CountBits (x : int)
、コンパイルエラーが発生しました:
error FS0001: This expression was expected to have type
int16
but here has type
int
の最初の引数Integral a
にHaskellのような制約を追加できるかどうか疑問に思っています。CountBitsWithRangedMask
または、元のコードを簡素化できる他のソリューションはありますか?