“做什么”和“哪里”混合? [英] How do `do` and `where` mix?

查看:107
本文介绍了“做什么”和“哪里”混合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在某些书中,我有以下代码片段:

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

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

hindent 缩进他们。现在我想介绍所有的大括号和分号,所以空白不再相关。只是因为我很好奇。



第二个例子表明,其中属于整个 runST $ do ... 表达式,但是第一个例子表明,的一部分在哪里去了mvec 语句。阅读 Haskell报告2.7章我尝试引入括号和分号在第一个例子中,像

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

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



为什么布局 hindent 产生第一个例子 mutableUpdateIO 有效的Haskell?不应该像在我上面的尝试中引入大括号和分号?

blocks既不属于 runST $ do ... 表达式也不属于 go n mvec 语句;它们属于 mutableUpdateIO n = ... 声明和 mutableUpdateST n = ... 声明。大括号和分号应该像这样:

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

$ / code>

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


只要包含布局列表的语法类别结束,也会插入一个大括号;也就是说,如果在关闭大括号合法的地方遇到非法名词,则会插入大括号。


其中是表达式中的非法词位,这将结束 do 块,并在其中插入一个大括号。这也解释了为什么生成的布局是合法的。

From some book I have the following code snippets

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

like hindent indents them. Now I want to introduce all braces and semicolons, so the whitespace isn't relevant any more. Just because I am curious.

The second example suggests, that the where belongs to the whole runST $ do ... expression, but the first example suggests, that the where is somehow a part of the go n mvec statement. Reading in Haskell Report Chapter 2.7 I tried to introduce braces and semicolons in the first example like

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;
  } ; }

But I get a parsing error. Why is that?

Why is the layout hindent produces for the first example mutableUpdateIO valid Haskell? Shouldn't the braces and semicolons be introduced like in my above try?

解决方案

The where blocks belong neither to the runST $ do ... expression nor to the go n mvec statement; they belong to the mutableUpdateIO n = ... declaration and the mutableUpdateST n = ... declaration. The braces and semicolons should go like this:

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;
  }

The relevant sentence from the informal description in the Report in chapter 2.7 is this:

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.

Since where is an illegal lexeme inside an expression, this ends the do block and a close brace is inserted there. This also explains why the layout hindent produced was legal.

这篇关于“做什么”和“哪里”混合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆