我正在尝试实现自己的仿函数实例并快速检查它们,并且遇到了类型的问题,这些类型不是Eq
的实例,即(->)
和IO
。我的尝试导致No instance for (Eq ...)
错误。
在(->)
案例中,我遇到了与Show
类似的错误,即No instance for (Show ...)
,并且能够通过添加Show (a -> b)
实例来修复此错误答案here。似乎我也可以通过类似地添加它们来解决缺少Eq
实例的问题。但是,this question on function equality指出在Haskell中创建Eq (a -> b)
的实例等同于暂停问题,因此不可能。
我不确定是否可以创建Eq IO a
的实例。在IO
案例中,我也遇到了No instance for (Arbitrary ...)
错误。
有没有办法快速检查函数类型(->)
的仿函数属性?有没有办法对IO
类型执行相同操作?
我的代码如下。
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