从无限浮动列表中删除零
remove zero from infinite float list
我想从无限的浮点数列表中采样,以供 QuickCheck 消费。但是,由于我打算使用除法,因此我想从该列表中删除 zero。这是一个概念上如此简单的问题,我想知道我是否可以通过列表理解来解决这个问题,如果不能,那将是在 Haskell?
中实现此目的的最简单方法
[x | x <- floats, x /= 0] -- this seems reasonable, but where do I get floats from?
我目前的解决方法(讨厌):
import Test.QuickTest
divGen :: Gen (Maybe Float)
divGen = do
x <- arbitrary
if x /= 0
then return $ Just x
else return Nothing
Could I do it with a list comprehension?
当然,这种理解对我来说很好。
Where do I get floats
from?
取决于你想成为什么样的人。
对于您的生成器代码,我唯一要说的是拒绝抽样是常用的技巧:
divGen = do
x <- arbitrary
if x /= 0 then return x else divGen
您可以使用 QuickCheck 的 suchThat
组合器生成满足给定谓词的 arbitrary
值:
divisor :: Gen Float
divisor = arbitrary `suchThat` (/= 0)
用法示例:
my_prop x = forAll divisor $ \d -> (x / d) * d =~= x
这已经在 QuickCheck 中,即 NonZero
。您的无限浮动列表可以建模为
nonZeroFloat :: Gen Float
nonZeroFloat = fmap getNonZero arbitrary
-- You probably want to use a shorter name:
infiniteListOfNonZeroFloats :: Gen [Float]
infiniteListOfNonZeroFloats = infiniteListOf nonZeroFloat
之后可以使用forAll
:
prop_something = forAll infiniteListOfNonZeroFloats $ \xs -> ...
-- or
prop_something = forAll (infinitelistOf $ getNonZero `fmap` arbitrary) $ \xs ->
...
请注意,使用NonZero
与模式匹配更流畅:
prop_nonzero :: NonZero Float -> ...
prop_nonzero (NonZero x) = ...
因此,如果您只想从列表中删除零,则可以执行以下操作:
函数定义:
withoutZeros:: (Eq a,Num a)->[a]->[a]
此代码将删除所有零。您可以通过更改 (/=).
中的条件来删除任何数字
withoutZeros =filter (/=0)
我在函数定义中使用了 (Eq a,Num a)
,因为比较(即 (/=)
)和 Num a->
需要 Eq a->
。这将允许您在 Integer 和 Float 列表上使用此函数。
我想从无限的浮点数列表中采样,以供 QuickCheck 消费。但是,由于我打算使用除法,因此我想从该列表中删除 zero。这是一个概念上如此简单的问题,我想知道我是否可以通过列表理解来解决这个问题,如果不能,那将是在 Haskell?
中实现此目的的最简单方法[x | x <- floats, x /= 0] -- this seems reasonable, but where do I get floats from?
我目前的解决方法(讨厌):
import Test.QuickTest
divGen :: Gen (Maybe Float)
divGen = do
x <- arbitrary
if x /= 0
then return $ Just x
else return Nothing
Could I do it with a list comprehension?
当然,这种理解对我来说很好。
Where do I get
floats
from?
取决于你想成为什么样的人。
对于您的生成器代码,我唯一要说的是拒绝抽样是常用的技巧:
divGen = do
x <- arbitrary
if x /= 0 then return x else divGen
您可以使用 QuickCheck 的 suchThat
组合器生成满足给定谓词的 arbitrary
值:
divisor :: Gen Float
divisor = arbitrary `suchThat` (/= 0)
用法示例:
my_prop x = forAll divisor $ \d -> (x / d) * d =~= x
这已经在 QuickCheck 中,即 NonZero
。您的无限浮动列表可以建模为
nonZeroFloat :: Gen Float
nonZeroFloat = fmap getNonZero arbitrary
-- You probably want to use a shorter name:
infiniteListOfNonZeroFloats :: Gen [Float]
infiniteListOfNonZeroFloats = infiniteListOf nonZeroFloat
之后可以使用forAll
:
prop_something = forAll infiniteListOfNonZeroFloats $ \xs -> ...
-- or
prop_something = forAll (infinitelistOf $ getNonZero `fmap` arbitrary) $ \xs ->
...
请注意,使用NonZero
与模式匹配更流畅:
prop_nonzero :: NonZero Float -> ...
prop_nonzero (NonZero x) = ...
因此,如果您只想从列表中删除零,则可以执行以下操作:
函数定义:
withoutZeros:: (Eq a,Num a)->[a]->[a]
此代码将删除所有零。您可以通过更改 (/=).
中的条件来删除任何数字withoutZeros =filter (/=0)
我在函数定义中使用了 (Eq a,Num a)
,因为比较(即 (/=)
)和 Num a->
需要 Eq a->
。这将允许您在 Integer 和 Float 列表上使用此函数。