gpt4 book ai didi

haskell - 在列表中使用 where

转载 作者:行者123 更新时间:2023-12-01 09:14:32 25 4
gpt4 key购买 nike

有没有办法在列表语法中使用 where 表达式?我想象这样的事情会起作用:

foo = [i where i = 1]

但编译产生:

error: parse error on input ‘where’

可以在列表中使用 let ... in:

foo = [let i = 1 in i]

所以我假设 wherelet 表现为不同的句法结构?

我知道可以这样做:

foo = [i] where i = 1

...但是对于更复杂的列表,ii = 1 之间的距离太远了,无法清楚 - 请参阅下面的上下文部分和想象更多的测试用例,而这个 testGroup 本身嵌套在一个列表中。


上下文

我在尝试编写可读的测试用例时遇到了这个问题:

testGroup "toInput"
[
testProperty "toInput '*'" (forAll others conversionFails)
where others = arbitrary `suchThat` (\c -> c `notElem` exclChars)
conversionFails c = toInput c == Nothing
]

let 的等价物在阅读 imo 时并不令人满意(更具体地说,当被其他测试用例包围时,testProperty 不在同一个缩进,因为它们更难理解)。

testGroup "toInput"
[
let others = arbitrary `suchThat` (\c -> c `notElem` exclChars)
conversionFails c = toInput c == Nothing
in
testProperty "toInput '*'" (forAll others conversionFails)
]

最佳答案

喜欢 Haskell Wiki article says :

It is important to know that let ... in ... is an expression, that is, it can be written wherever expressions are allowed. In contrast, where is bound to a surrounding syntactic construct, like the pattern matching line of a function definition.

简而言之,where 绑定(bind)到函数声明的子句,而 let 在表达式中的范围更广。如果你写where,它对整个子句都是可见的,比如:

f a | a > 0 = g b b
| otherwise = b
where b = g a a

所以这里的 where 对两个守卫是可见的,而 let 的范围更广。如果你写let y = f x in y * y,那么那个y只是可见in ...部分。例如我们可以这样写:

Prelude> let a = 4 in (let a = 2 in a) + a
6

所以这里的内部 a2 而外部是 4。这最终可能会非常令人困惑。如果我们在 where 子句中定义具有相同名称的变量,这将导致名称冲突。

如果您的代码示例是单个函数,您当然可以将其移出列表定义,例如:

foo exclChars = 
testGroup "toInput" [testProperty "toInput '*'" (forAll others conversionFails)]
where others = arbitrary `suchThat` (`notElem` exclChars)
conversionFails = isNothing . toInput

关于haskell - 在列表中使用 where,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48076189/

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