1

I have two properties that a function foo must satisfy:

prop_1 :: [Int] -> Bool
prop_1 xs = foo xs id == xs 

prop_2 :: [Int] -> (Int -> Int) -> (Int -> Int) -> Bool
prop_2 xs f g = foo (foo xs f) g == foo xs (g . f)

I am trying to check whether the above properties satisfy the following function using quickCheck:

foo :: [a] -> (a -> b) -> [b]
foo xs f = []

When I tried running quickCheck with prop_2 I get the following error:

quickCheck(prop_2)

<interactive>:18:1: error:
     No instance for (Show (Int -> Int))
        arising from a use of 'quickCheck'
        (maybe you haven't applied a function to enough arguments?)
     In the expression: quickCheck (prop_2)
      In an equation for 'it': it = quickCheck (prop_2)

I am not sure why I am getting this error and how I can resolve it. Any insights are appreciated.

2
  • The arguments of prop_2 must be Showable, since QuickCheck should be able to show with what parameters the prop_2 was disproven. Commented Jun 28, 2019 at 10:14
  • You can import ShowFunctions for that. Commented Jun 28, 2019 at 10:16

2 Answers 2

2

You can use QuickCheck's support for generation of random shrinkable, showable functions by changing the property to

prop_2 :: [Int] -> Fun Int Int -> Fun Int Int -> Bool
prop_2 xs (Fn f) (Fn g) = foo (foo xs f) g == foo xs (g . f)

and then you'll see something more useful than <function> for counterexamples.

Sign up to request clarification or add additional context in comments.

2 Comments

What is <function> in quickCheck? I tried running quickCheck with another property and I got the following result: Failed (after 2 tests and 1 shrink) <function> "" "".
It isn't "in QuickCheck", it's how the instance in Text.Show.Functions works (hackage.haskell.org/package/base-4.12.0.0/docs/…)
1

As the documentation on QuickCheck says:

However, before we can test such a property, we must see to it that function values can be printed (in case a counter-example is found). That is, function types must be instances of class Show. To arrange this, you must import module ShowFunctions into every module containing higher-order properties of this kind. If a counter-example is found, function values will be displayed as "<function>"

So you can fix this by importing a module like:

import Text.Show.Functions

prop_1 :: [Int] -> Bool
prop_1 xs = foo xs id == xs 

prop_2 :: [Int] -> (Int -> Int) -> (Int -> Int) -> Bool
prop_2 xs f g = foo (foo xs f) g == foo xs (g . f)

1 Comment

It's really much better to use the Fun type as Alexey Romanov explains than to use a bogus orphan instance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.