简体   繁体   English

我的 quickCheck 类型声明有什么问题?

[英]What's wrong with my quickCheck type declaration?

I roll my own elem function called elem'我推出了自己的elem function,称为elem'

elem' :: (Eq a) => a -> [a] -> Bool
elem' n ys = foldl (\acc p -> if (p == n) then True else False) False ys

Seems to work but I want to quickCheck it in GHCi so I import Test.QuickCheck似乎可以工作,但我想在 GHCi 中快速检查它,所以我import Test.QuickCheck

verboseCheck (\a -> (\xs ->( (elem' a xs) == (elem a xs)) ) )

Without a type declaration on the test function it tests ok, but that's because it's only testing null inputs.如果在测试 function 上没有类型声明,它可以测试,但那是因为它只测试 null 输入。

Something is wrong with my type declaration for the test function:我的测试 function 的类型声明有问题:

verboseCheck (\a->(\xs->((elem' a xs)==(elem a xs))) :: Int->[Int]->Bool)
verboseCheck (\a->(\xs->((elem' a xs)==(elem a xs))) :: Char->[Char]->Bool)

Error for first one:第一个错误:

• Couldn't match expected type ‘[Int] -> Bool’
                  with actual type ‘Bool’
    • Possible cause: ‘(==)’ is applied to too many arguments
      In the expression: ((elem' a xs) == (elem a xs))
      In the expression:
          (\ xs -> ((elem' a xs) == (elem a xs))) :: Int -> [Int] -> Bool
      In the first argument of ‘verboseCheck’, namely
        ‘(\ a
            -> (\ xs -> ((elem' a xs) == (elem a xs))) ::
                 Int -> [Int] -> Bool)’

<interactive>:258:39: error:
    • Couldn't match expected type ‘[()]’ with actual type ‘Int’
    • In the second argument of ‘elem'’, namely ‘xs’
      In the first argument of ‘(==)’, namely ‘(elem' a xs)’
      In the expression: ((elem' a xs) == (elem a xs))

<interactive>:258:54: error:
    • Couldn't match expected type ‘[()]’ with actual type ‘Int’
    • In the second argument of ‘elem’, namely ‘xs’
      In the second argument of ‘(==)’, namely ‘(elem a xs)’
      In the expression: ((elem' a xs) == (elem a xs))

This happens because Haskell thinks that you're constraining the return type of the lambda expression \a->(\xs->((elem' a xs)==(elem a xs))) .发生这种情况是因为 Haskell 认为您正在限制 lambda 表达式\a->(\xs->((elem' a xs)==(elem a xs)))返回类型 This may be easier to see if you format the expression a bit more idiomatically:如果您更习惯地格式化表达式,这可能更容易看出:

\a -> (\xs -> ((elem' a xs) == (elem a xs)))

To the interpreter/compiler, this looks like a lambda expression that returns another expression.对于解释器/编译器,这看起来像一个返回另一个表达式的 lambda 表达式。 All good.都好。

However, when you attempt to annotate it with a type:但是,当您尝试使用类型对其进行注释时:

\a -> (\xs -> ((elem' a xs) == (elem a xs))) :: Int -> [Int] -> Bool

Haskell thinks that you're annotating the return type , ie the right-most part closest associated with the type annotation: (\xs -> ((elem' a xs) == (elem a xs))) . Haskell 认为您正在注释返回类型,即与类型注释最接近的最右侧部分: (\xs -> ((elem' a xs) == (elem a xs)))

Surround the entire lambda expression with brackets before applying the type:在应用类型之前,用括号将整个 lambda 表达式括起来:

(\a -> (\xs -> ((elem' a xs) == (elem a xs)))) :: Int -> [Int] -> Bool

You can now verboseCheck that expression:您现在可以verboseCheck该表达式:

Prelude Test.QuickCheck> verboseCheck ((\a -> (\xs -> ((elem' a xs) == (elem a xs)))) :: Int -> [Int] -> Bool)
Passed:
0
[]

Passed:
0
[]

Passed:
0
[-2,0]

Failed:
1
[2,1,-1]

Passed:
0
[2,1,-1]

Passed:
1
[]

Failed:
1
[1,-1]

Passed:
0
[1,-1]

Passed:
1
[]

Passed:
1
[-1]

Passed:
1
[1]

Passed:
1
[0,-1]

Passed:
1
[1,1]

Failed:
1
[1,0]

Passed:
0
[1,0]

Passed:
1
[]

Passed:
1
[0]

Passed:
1
[1]

Passed:
1
[0,0]

*** Failed! Falsified (after 4 tests and 2 shrinks):
1
[1,0]

Most of the brackets, however, are redundant, which is probably what's causing the confusion.然而,大多数括号都是多余的,这可能是造成混乱的原因。 You can simplify the expressions to this:您可以将表达式简化为:

verboseCheck ((\a xs -> elem' a xs == elem a xs) :: Int -> [Int] -> Bool)
verboseCheck ((\a xs -> elem' a xs == elem a xs) :: Char -> [Char] -> Bool)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM