是否可以快速检查函数类型的仿函数属性?

时间:2017-05-22 14:10:06

标签: haskell typeclass functor quickcheck

我正在尝试实现自己的仿函数实例并快速检查它们,并且遇到了类型的问题,这些类型不是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

0 个答案:

没有答案