gpt4 book ai didi

haskell - 为什么我不能让 `where` 在 Hspec 中工作

转载 作者:行者123 更新时间:2023-12-05 01:55:39 25 4
gpt4 key购买 nike

我正在努力解决 do block 中 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 子句只能附加到函数或大小写绑定(bind),并且必须在右侧主体之后。

当编译器看到 where 时,它知道您的 spec = ... 等式的 RHS 结束了。然后它使用缩进来确定 where 中的定义 block 延伸了多远(在这种情况下只是单个 f = id)。接下来,编译器正在寻找下一个模块范围定义的开始,但是缩进的 describe "bar"$ do 对于定义的开始是无效的,这是你得到的错误。

您不能随意将 where 子句插入到函数定义的中间。它可用于在绑定(bind)的整个 RHS 范围内添加辅助绑定(bind);它不能用于在任意子表达式的范围内添加本地绑定(bind)。

但是 let ... in ... 正是出于这个目的。由于您在每个 describe 下使用 do block ,您还可以使用 let 语句(使用 do 的其余部分 block 来分隔本地绑定(bind)的范围,而不是 let ... in ... 表达式的 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)

关于haskell - 为什么我不能让 `where` 在 Hspec 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70176332/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com