gpt4 book ai didi

haskell - `do` 和 `where` 怎么混?

转载 作者:行者123 更新时间:2023-12-03 15:02:45 25 4
gpt4 key购买 nike

从某本书中,我有以下代码片段

mutableUpdateIO :: Int -> IO (MV.MVector RealWorld Int)
mutableUpdateIO n = do
mvec <- GM.new (n + 1)
go n mvec
where
go 0 v = return v
go n v = (MV.write v n 0) >> go (n - 1) v

mutableUpdateST :: Int -> V.Vector Int
mutableUpdateST n =
runST $ do
mvec <- GM.new (n + 1)
go n mvec
where
go 0 v = V.freeze v
go n v = (MV.write v n 0) >> go (n - 1) v

喜欢 hindent缩进它们。现在我想介绍所有大括号和分号,因此空格不再相关。只是因为我很好奇。

第二个例子表明, where属于整体 runST $ do ...表达式,但第一个示例表明 where 是 go n mvec 的一部分陈述。阅读 Haskell Report Chapter 2.7我尝试在第一个示例中引入大括号和分号,例如
mutableUpdateIO :: Int -> IO (MV.MVector RealWorld Int)
mutableUpdateIO n = do {
mvec <- GM.new (n + 1);
go n mvec;
where {
go 0 v = return v;
go n v = (MV.write v n 0) >> go (n - 1) v;
} ; }

但我得到一个解析错误。这是为什么?

为什么是布局 hindent为第一个示例生成 mutableUpdateIO有效的 haskell ?不应该像我上面的尝试那样引入大括号和分号吗?

最佳答案

where block 都不属于runST $ do ...表达式也不是 go n mvec陈述;它们属于 mutableUpdateIO n = ...声明和 mutableUpdateST n = ...宣言。大括号和分号应该是这样的:

mutableUpdateIO :: Int -> IO (MV.MVector RealWorld Int)
mutableUpdateIO n = do {
mvec <- GM.new (n + 1);
go n mvec;
} where {
go 0 v = return v;
go n v = (MV.write v n 0) >> go (n - 1) v;
}

第 2.7 章报告中的非正式描述中的相关句子是:

A close brace is also inserted whenever the syntactic category containing the layout list ends; that is, if an illegal lexeme is encountered at a point where a close brace would be legal, a close brace is inserted.



由于 where是表达式中的非法词素,这将结束 do block 并在那里插入一个右大括号。这也解释了为什么生成的布局是合法的。

关于haskell - `do` 和 `where` 怎么混?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45306764/

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