2017-07-25 59 views
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 

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?不應該在我的上述嘗試中引入大括號和分號嗎?

+0

'where'與'do' afaik分開。我認爲哪裏會自動具有功能範圍。 – Carcigenicate

+0

關聯:https://stackoverflow.com/questions/9721354/in-haskell-what-is-the-scope-of-a-where-clause-when-dealing-with-guards – Carcigenicate

+10

'do ...'是一個表達。 「where」從不附加到表達式,只附加到聲明。 – melpomene

回答

9

where塊既不屬於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報告非正式說明有關一句話是這樣的:

一個右括號也被插入時包含的詞類佈局列表結束;也就是說,如果在緊密大括號合法的地方遇到非法的詞位,則會插入緊密大括號。

由於where是表達內的非法語義,這結束do塊和一個靠近支架被插入那裏。這也解釋了爲什麼生成的佈局合理。