Is it possible to quickcheck functor properties of the function type?

Viewed 287

I am trying to implement my own functor instances and quickcheck them, and have run into issues on typeclasses which are not instances of Eq, namely (->) and IO. My attempts result in a No instance for (Eq ...) error.

In the (->) case I had run into a similar error with Show, i.e. No instance for (Show ...), and was able to fix that by adding a Show (a -> b) instance as suggested in an answer here. It would seem that I might be able to solve also the lack of Eq instances by adding them similarly. However, this question on function equality notes that that in Haskell creating an instance of Eq (a -> b) is equivalent to the halting problem and therefore impossible.

I'm not sure whether creating an instance of Eq IO a is possible. In the IO case I also run into a No instance for (Arbitrary ...) error.

Is there some way to quickcheck the functor properties of the function type (->)? Is there some way to do the same for the IO type?

My code is as follows.

import Prelude hiding (Functor, fmap)
import Test.QuickCheck
import Test.QuickCheck.Function

class Functor f where
  fmap :: (a -> b) -> f a -> f b

instance Functor IO where
  fmap h f = f >>= (pure . h)

instance Functor ((->) e) where
  fmap = (.)

data T a = T

prop_functorid :: (Functor f, Eq (f a)) => T (f a) -> f a -> Bool
prop_functorid T x = fmap id x == x

prop_functorcompose :: (Functor f, Eq (f c)) => T (f a) -> T b -> T c -> f a -> Fun a b -> Fun b c -> Bool
prop_functorcompose T T T x (apply -> g) (apply -> h) =
  fmap (h . g) x == (fmap h . fmap g) x

instance Show (a -> b) where
  show a= "function"

prop_function :: IO ()
prop_function = do
  quickCheck $ prop_functorid (T :: T (String -> String))
  quickCheck $ prop_functorcompose (T :: T (String -> String)) (T :: T String) (T :: T String)

prop_io :: IO ()
prop_io = do
  quickCheck $ prop_functorid (T :: T (IO String))
  quickCheck $ prop_functorcompose (T :: T (IO String)) (T :: T String) (T :: T String)

main = do
  prop_function
  prop_io
0 Answers
Related