从无限浮点列表中删除零

时间:2016-02-16 06:07:46

标签: haskell list-comprehension quickcheck

我想从 QuickCheck 消费的无限浮动列表中进行抽样。但是,由于我打算使用除法,我想从该列表中删除。这是一个概念上简单的问题我想知道我是否可以用列表理解来做,如果没有,哪个是在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

4 个答案:

答案 0 :(得分:6)

您可以使用QuickCheck的suchThat组合器生成满足给定谓词的arbitrary值:

divisor :: Gen Float
divisor = arbitrary `suchThat` (/= 0)

使用示例:

my_prop x = forAll divisor $ \d -> (x / d) * d =~= x

答案 1 :(得分:5)

已经在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) = ...

答案 2 :(得分:1)

因此,如果您仅打算从列表中删除零,则可以执行以下操作:

  1. 功能定义:

    withoutZeros:: (Eq a,Num a)->[a]->[a] 
    
  2. 此代码将删除所有零。您只需更改(/ =)内的条件即可删除任何数字。

    withoutZeros =filter (/=0)  
    

我在函数定义中使用了(Eq a,Num a),因为比较(即Eq a->(/=)需要Num a->。这样一来,您就可以在整数列表和浮动列表中使用此功能。

答案 3 :(得分:0)

  

我可以使用列表理解吗?

当然,这种理解对我来说很好。

  

我从哪里获取floats

取决于你想要的东西。

对于您的生成器代码,我唯一的评论是拒绝采样是通常的技巧:

divGen = do
    x <- arbitrary
    if x /= 0 then return x else divGen