2017-07-25 2 views
7

`do`と` where`はどうやってミックスされますか?私は、次のコードを持っているいくつかの本から

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 ...という表現に属していますが、最初の例では、どこが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-withguards – 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ブロックを終了し、閉じるブレースが挿入され、発現内部不正語彙素です。これはまた、なぜ生成されたレイアウトのヒントが合法であったかを説明する。

関連する問題