在没有输入参数告诉您类型时,基于类型创建事物数组

  • 本文关键字:类型 于类型 数组 创建 参数 haskell
  • 更新时间 :
  • 英文 :


有时我有一组测试,我想在一堆不同的类型上运行。这里有一个简单的例子,说明我通常是怎么做的:

import           Test.Framework                                (Test)
import           Test.Framework.Providers.QuickCheck2          (testProperty)
import           Test.QuickCheck
additionCommutes :: (Eq a, Num a) => a -> a -> Bool
additionCommutes x y = x + y == y + x
divisionByItselfIsOne :: (Eq a, Ord a, Fractional a) => a -> Property
divisionByItselfIsOne x = x > 0 ==> x / x == 1
-- pretend rounding errors won't occur, this is just an example

floatTests :: [Test]
floatTests = [
testProperty "float addition commutes"
(additionCommutes :: Float -> Float -> Bool),
testProperty "float divided by itself is 1"
(divisionByItselfIsOne :: Float -> Property)
]
doubleTests :: [Test]
doubleTests = [
testProperty "double addition commutes"
(additionCommutes :: Double -> Double -> Bool),
testProperty "double divided by itself is 1"
(divisionByItselfIsOne :: Double -> Property)
]

但是我宁愿避免重复列出每种类型的测试。(可能会涉及很多测试。)我想定义一次测试列表,然后为每种类型实例化它。像这样…

numberTests :: (Eq a, Ord a, Num a, Fractional a) => [Test] for the type "a"
numberTests = [
testProperty "double addition commutes"
(additionCommutes :: a -> a -> Bool),
testProperty "double divided by itself is 1"
(divisionByItselfIsOne :: a -> Property)
]

floatTests = numberTests :: [Test] for the type "float"
doubleTests = numberTests :: [Test] for the type "double"

当然,这在Haskell中是无效的。我有一种感觉,可能有一些神奇的类型级编程技术,我可以用它来完成这个。我浏览了马奎尔的《用类型思考》,但我仍然看不出如何解决这个问题。有什么建议吗?

如果有一种技术可以在原则上工作,但不能很好地与QuickCheck的反射东西一起工作,那很好——我更感兴趣的是建立我的类型级编程技能,而不是解决这个特殊的问题。

你很接近了:

{-# Language AllowAmbiguousTypes #-}
{-# Language ScopedTypeVariables #-}
{-# Language TypeApplications #-}
--             vvvvvvvvv
numberTests :: forall a. (Eq a, Ord a, Num a, Fractional a) => [Test]
numberTests = -- just like in the question
--                        vvvvvvv
floatTests  = numberTests @Float
doubleTests = numberTests @Double

你甚至不需要特别命名floatTestsdoubleTests;可以写成

allTests = numberTests @Float ++ numberTests @Double

如果你想的话

相关内容

  • 没有找到相关文章

最新更新