[英]Why am I getting an ioctl error in Visual Studio but not in Stack while trying to implement multiple test files in Hspec?
[英]Why cannot I get `where` to work in Hspec
我正在努力解决do
块中where
的语义,特别是Test.Hspec
。 以下作品:
module ExampleSpec where
import Test.Hspec
import Test.QuickCheck
spec :: Spec
spec = do
describe "foo" $ do
let
f = id
in
it "id" $ property $
\x -> f x `shouldBe` (x :: Int)
describe "bar" $ do
it "id" $ property $
\x -> x `shouldBe` (x :: Int)
这不会:
module ExampleSpec where
import Test.Hspec
import Test.QuickCheck
spec :: Spec
spec = do
describe "foo" $ do
it "id" $ property $
\x -> f x `shouldBe` (x :: Int)
where
f = id
describe "bar" $ do
it "id" $ property $
\x -> x `shouldBe` (x :: Int)
它失败了:
/mnt/c/haskell/chapter15/tests/ExampleSpec.hs:13:5: error: parse error on input ‘describe’
|
13 | describe "bar" $ do
| ^^^^^^^^
我做错了什么还是这是某种固有的限制where
?
这是为 where 块的范围规则服务的语法限制。 在where
块中,模式匹配中绑定的值位于 scope 中,而where
块中定义的值位于 scope 中,用于该模式匹配中的保护。 因此,必须将where
块附加到至少可能存在模式匹配和守卫的位置。 这最终成为值声明和 case 表达式的分支。 在您的第二个示例中,您试图将where
块附加到任意表达式,这不是他们打算做的。
where
子句只能附加到 function 或大小写绑定,并且必须位于右侧正文之后。
当编译器看到where
时,它就知道你的spec =...
等式的 RHS 已经结束。 然后它使用缩进来确定where
中的定义块扩展了多远(在这种情况下只是单个f = id
)。 之后编译器正在寻找下一个模块范围定义的开始,但是缩进的describe "bar" $ do
对于定义的开始是无效的,这是您得到的错误。
您不能将where
子句随机插入 function 定义的中间。 它只能用于在 scope 中在绑定的整个 RHS 上添加辅助绑定; 它不能用于在 scope 中为任意子表达式添加本地绑定。
然而,正是为了这个目的, let... in...
。 而且由于您在每个describe
下使用do
块,您还可以使用let
语句(使用do
块的其余部分来分隔本地绑定的 scope,而不是in
部分let... in...
表达式)。 所以你可以这样做:
spec = do
describe "foo" $ do
let f = id
it "id" $ property $
\x -> f x `shouldBe` (x :: Int)
describe "bar" $ do
it "id" $ property $
\x -> x `shouldBe` (x :: Int)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.