haskell - QuickCheck 如何检测数据类型?
问题描述
如果我们定义一个这样的函数
fun :: Int -> Property
然后运行
quickCheck fun
quickCheck 开始生成 Int 类型的随机数据。问题是 quickCheck 如何检测 fun 的参数数据类型是 Int 而不是任何其他数据类型?如果我把问题说得更笼统,我应该问一下,如果我们有这样一个叫做 fun 的函数
fun :: datatype_1 -> datatype_2 -> ... -> datatype_n -> Property
quickCheck 如何检测每个单独的 datatype_1、datatype_2、... 和 datatype_n 的类型?还有它如何检测函数 fun 需要多少个参数?
解决方案
粗略地说,这就是类型类的工作方式。可以申报
class C a where
foo :: a -> Bool
接着
instance C (Int -> Bool) where
foo f = f 42
instance C (String -> Bool) where
foo f = f "hello"
instance C (String -> [Int]) where
foo f = sum (f "hello") > 42
等等。
这具有明显的效果,可以foo
“检测”其参数的类型f
并采取相应的行动。实际上,发生的事情是 Haskell 执行类型推断,在此期间选择适当的实例——在编译时。在运行时,不会发生“类型检测”;实际上,类型在编译后会被擦除,并且在运行时没有可用的类型信息,因此无法检测到f
属于哪个类型。
当然,实际的 QuickCheck 机制要复杂得多。为了处理具有任意数量参数的函数,使用了一组“递归instance
”,可以说,每次“递归调用”处理每个参数。这是一种相当棘手的技术,也用于printf
其他“可变参数”函数。如果您不熟悉类型类,我不建议您从如此复杂的技巧开始学习它们。
推荐阅读
- node.js - 无法获取授权代码:错误:证书链中的自签名证书 - NodeJS 适配器 Keycloak
- java - JSOUP:提取文本之间
我要提取的文本
- mysql - wp-options 表大尺寸非常快
- c# - 使用 .net api 通过 Google 登录
- python - FileNotFoundError:[Errno 2] 没有这样的文件或目录:找不到文件的路径
- java - 为什么我在 java regex 中制作模式时未能解决第一组 (\\1)?
- javascript - 从对象数组中查找具有最大 ID 的项目
- docusignapi - API 计划与电子签名计划
- amazon-web-services - 在 s3 键中使用斜杠字符
- firebase - 如何找到 Google Firebase 数据库的所有者?