Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 哈斯凯尔为什么要施舍;不明确类型变量“;错误?_List_Function_Haskell_Recursion_Quickcheck - Fatal编程技术网

List 哈斯凯尔为什么要施舍;不明确类型变量“;错误?

List 哈斯凯尔为什么要施舍;不明确类型变量“;错误?,list,function,haskell,recursion,quickcheck,List,Function,Haskell,Recursion,Quickcheck,一个过去的问题问我;要定义一个函数p::[a]->[a],该函数在列表中每隔两项交换一次。您的函数应该将第一项与第二项(第三项)交换 第四个,等等。通过列表定义一个,通过递归定义另一个 这就是我想到的: import Test.QuickCheck p :: [a] -> [a] p [] = [] p xs = concat [ [y,x] | ((x,y),i) <- zip (zip xs (tail xs)) [1..], odd i] q :: [a] -> [a]

一个过去的问题问我;要定义一个函数p::[a]->[a],该函数在列表中每隔两项交换一次。您的函数应该将第一项与第二项(第三项)交换 第四个,等等。通过列表定义一个,通过递归定义另一个

这就是我想到的:

import Test.QuickCheck
p :: [a] -> [a]
p [] = []
p xs = concat [ [y,x] | ((x,y),i) <- zip (zip xs (tail xs)) [1..], odd i]
q :: [a] -> [a]
q [] = []
q (x:y:zs) | even (length zs) = [y,x] ++ q zs
           | otherwise = error "The list provided is not of even length"
prop_2 xs = even (length xs) ==> p xs == q xs
check2 = quickCheck prop_2
import Test.QuickCheck
p::[a]->[a]
p[]=[]
p xs=concat[[y,x]|((x,y),i)[a]
q[]=[]
q(x:y:zs)|偶数(长度zs)=[y,x]++qzs
|否则=错误“提供的列表长度不均匀”
prop_2 xs=偶数(长度xs)=>pxs==qxs
检查2=快速检查项目2
函数工作正常,但我想检查这两个函数是否相同,因此我将快速检查放在下面;但由于某种原因,这给了我一个错误 “由于使用prop_2而导致类型变量[a0]不明确”

我只是不明白这里出了什么问题,我看起来很理智。。。
Haskell到底在抱怨什么???

让我们先评论一下
check2
,然后询问GHCi
prop_2
的类型:

*Main> :t prop_2
prop_2 :: Eq a => [a] -> Property
好的,按照您编写的
prop_2
的方式,它适用于equality类中任何元素类型的列表

现在,您想将
prop_2
传递给
quickCheck
函数。下面让我们看看
quickCheck
的类型:

*Main> :t quickCheck
quickCheck :: Testable prop => prop -> IO ()
这个函数实际上有一个非常通用的类型。它适用于
可测试
类中的任何东西。那么这个
可测试
类是如何工作的呢?这里有几个基本实例,例如:

instance Testable Bool
instance Testable Property  -- this is a simplification, but it's more or less true
这些实例在QuickCheck库中定义,并告诉您可以进行快速检查 常量布尔值以及类型属性的元素

现在,测试不依赖于任何输入的属性并不特别有趣。有趣的例子是:

instance (Arbitrary a, Show a, Testable prop) => Testable (a -> prop)
这意味着,如果您知道如何生成特定类型的随机值(
arbitral a
)以及如何显示该类型的值(
show a
),那么您还可以测试从该类型
a
到已可测试类型
prop
的函数

为什么?因为QuickCheck就是这样运行的。在这种情况下,QuickCheck将参考
任意
实例,以生成
a
类型的随机测试用例,将函数应用于每个测试用例,并检查结果是否为正。如果任何测试失败,它将打印一条消息通知您测试失败,它将打印测试用例(这就是为什么还有
Show
需求)

现在,在我们的情况下,这意味着我们应该能够快速检查
prop_2
:这是一个产生
属性的函数。重要的是函数参数(类型
[a]
,只要
Eq a
保持不变)是类
任意
的成员,也是类
显示
的成员

在这里,我们找到了错误的根源。可用的信息不足以得出这样的结论。正如我在开始时所说,
prop_2
适用于任何允许相等的元素类型的列表。没有内置规则说所有这些类型都是
任意的
显示的
。但即使有s、 QuickCheck应该生成什么样的列表?它应该生成布尔值列表、单位类型列表、函数列表、字符列表、整数列表吗?如此多的选项和元素类型的选择可能会影响您是否发现bug。(请考虑GHC会选择单位类型
()
只包含一个元素。那么您的属性将适用于保留输入列表长度的任何两个函数
p
q
,而不管它们是否具有您想要的交换属性。)

这就是为什么您需要向GHC提供额外的类型信息,以便GHC能够解析用于列表的元素类型。这样做非常简单。您可以对
prop_2
本身进行注释:

prop_2 :: [Integer] -> Property
或者,如果您不希望这样做(因为您可能希望在不同类型的列表上运行测试,而无需重新实现
prop_2
),则可以在调用
quickCheck
时添加类型注释:

check2 = quickCheck (prop_2 :: [Integer] -> Property)
现在代码已编译,我们可以运行
check2

Main*> check2
+++ OK, passed 100 tests.

假设你是GHC。你为快速检查测试生成了什么类型的列表?嗨,非常感谢你的回答!但我仍然不明白(很抱歉,我是一个完全的初学者,刚刚开始在大学编程,现在正在踢我的屁股…),那么是不是Haskell不知道什么是“prop_2”所以我必须告诉它吗?>prop_2 xs=偶数(长度xs)==>pxs==qxs取[a]并将其转换为Int,然后给出Bool,所以>p:[a]->Int->Bool,但我不确定在这之后对于“==>pxs==qxs”…@Brad我已经大大扩展了答案。我希望这有帮助。