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