繁体   English   中英

为什么我不能在 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.

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