wid*_*pil 4 haskell quickcheck
我推出了自己的elem函数,称为elem'
elem' :: (Eq a) => a -> [a] -> Bool
elem' n ys = foldl (\acc p -> if (p == n) then True else False) False ys
Run Code Online (Sandbox Code Playgroud)
似乎有效,但我想在 GHCi 中快速检查它,所以我 import Test.QuickCheck
verboseCheck (\a -> (\xs ->( (elem' a xs) == (elem a xs)) ) )
Run Code Online (Sandbox Code Playgroud)
在测试函数上没有类型声明它测试正常,但那是因为它只测试空输入。
我的测试函数类型声明有问题:
verboseCheck (\a->(\xs->((elem' a xs)==(elem a xs))) :: Int->[Int]->Bool)
verboseCheck (\a->(\xs->((elem' a xs)==(elem a xs))) :: Char->[Char]->Bool)
Run Code Online (Sandbox Code Playgroud)
第一个错误:
• 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))
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为 Haskell 认为您限制了 lambda 表达式的返回类型\a->(\xs->((elem' a xs)==(elem a xs)))。如果您更习惯地格式化表达式,这可能更容易看到:
\a -> (\xs -> ((elem' a xs) == (elem a xs)))
Run Code Online (Sandbox Code Playgroud)
对于解释器/编译器,这看起来像一个返回另一个表达式的 lambda 表达式。都好。
但是,当您尝试使用类型对其进行注释时:
\a -> (\xs -> ((elem' a xs) == (elem a xs))) :: Int -> [Int] -> Bool
Run Code Online (Sandbox Code Playgroud)
Haskell 认为您正在注释返回类型,即与类型注释最接近的最右侧部分:(\xs -> ((elem' a xs) == (elem a xs)))。
在应用类型之前用括号将整个 lambda 表达式括起来:
(\a -> (\xs -> ((elem' a xs) == (elem a xs)))) :: Int -> [Int] -> Bool
Run Code Online (Sandbox Code Playgroud)
您现在可以使用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]
Run Code Online (Sandbox Code Playgroud)
然而,大多数括号都是多余的,这可能是造成混淆的原因。您可以将表达式简化为:
verboseCheck ((\a xs -> elem' a xs == elem a xs) :: Int -> [Int] -> Bool)
verboseCheck ((\a xs -> elem' a xs == elem a xs) :: Char -> [Char] -> Bool)
Run Code Online (Sandbox Code Playgroud)