Haskell 类型构造函数作为表达式的参数
我使用hspec和QuickCheck来验证函子实例的函子定律。我有很多功能Haskell 类型构造函数作为表达式的参数,haskell,Haskell,我使用hspec和QuickCheck来验证函子实例的函子定律。我有很多功能 functorIdentity :: (Functor f, Eq (f a)) => f a -> Bool 及 然后我将使用如下代码块测试这两个: testListFunctorness :: IO () testListFunctorness = hspec $ do describe "list" $ do it "should obey functor identity"
functorIdentity :: (Functor f, Eq (f a)) => f a -> Bool
及
然后我将使用如下代码块测试这两个:
testListFunctorness :: IO ()
testListFunctorness =
hspec $ do
describe "list" $ do
it "should obey functor identity" $ do
property (functorIdentity :: [Int] -> Bool)
it "should obey functor composition" $ do
property
(functorComposition :: (Fun Int String) -> (Fun String Int) -> [Int] -> Bool)
问题是,要为不同的Functor实例测试相同的属性,我需要复制除[Int]
s以外的所有内容:
testMaybeFunctorness :: IO ()
testMaybeFunctorness =
hspec $ do
describe "maybe" $ do
it "should obey functor identity" $ do
property (functorIdentity :: Maybe Int -> Bool)
it "should obey functor composition" $ do
property
(functorComposition :: (Fun Int String) -> (Fun String Int) -> Maybe Int -> Bool)
我觉得我应该能够编写一个表达式,它在不同的Functor
实例上以某种方式是多态的,但我甚至不知道如何开始
如何方便地为多个不同的
Functor
重用该测试逻辑块?您可以做的是显式地将所需类型传递给testFunctorness
:
import Data.Proxy
testFunctorness::对于所有a。函子a=>代理a->IO()
测试函数性=
hspec$do
描述“类型”$do
它“应该服从函子标识”$do
属性(functionIdentity::a Int->Bool)
它“应该服从函子组合”$do
财产
(functorComposition::(趣味字符串)->(趣味字符串)->a Int->Bool)
调用看起来像testFunctorness(Proxy::Proxy[])
您需要启用
{-#语言范围的TypeVariables#-}
,以便函数中的a
引用类型签名中的a
。然后需要所有的forall
让类型检查器知道a
应该是词汇范围。我99%确定这里有AB问题,但我看不出B是什么:)啊,数据。代理很好。我在约束中使用了任意(一个Int)、Show(一个Int)、Eq(一个Int)
来进行快速检查,但除此之外,它是完美的。
testMaybeFunctorness :: IO ()
testMaybeFunctorness =
hspec $ do
describe "maybe" $ do
it "should obey functor identity" $ do
property (functorIdentity :: Maybe Int -> Bool)
it "should obey functor composition" $ do
property
(functorComposition :: (Fun Int String) -> (Fun String Int) -> Maybe Int -> Bool)