ここで物事を定義する3つの類似した(しかし異なる)方法があります:
特定の定義の後に句を付加できwhereます。ほとんどの場合、方程式スタイルのバインディングです。letしたがって、関数の最後、または周囲のwhere句で定義されたものの後に1つ置くことができます。
一方、let x = ... in ...は、後の部分に評価される式inであり、後の部分が表示される唯一の場所letです。
ブロック内には、スコープの暗黙的なネストがすでに存在するため(最初に定義された後に表示されます)、単独でdo使用できます。let x = ...これは実際には前のフォームと同じです。do後のブロックの残りの部分letは事実上そのin ...部分です。
ブロック内で定義されたものを使用するローカル定義が必要な場合do、唯一の選択肢は3番目です(または他の値を引数として渡します)。ただし、例のような独立したヘルパー関数の場合は、どのスタイルでも機能します。それぞれを示すための例を次に示します。
最初のスタイル。ここでは、句で定義されている他のものを含め、のfuncどこにでも表示されます。foowhere
foo = do ...
mapM_ func aList
...
return aValue
where func x = x + 1
2番目のスタイル。ここでfuncは、式の内部にのみ表示されます。この場合は、ブロックlet全体です。do
foo = let func x = x + 1
in do
...
mapM_ func aList
...
return aValue
そして3番目のスタイルは、doブロック内でそれを定義します。この場合、は;funcの後にのみ表示されます。let最初...はまだ定義されていません。
foo = do ...
let func x = x + 1
mapM_ func aList
...
return aValue
ああ、そして良い意味で:let ... in ...は式なので、式がある場所ならどこでも使用して、いくつかのローカル定義に名前を付けることができます。したがって、別の例を次に示します。
foo = do ...
let func x = x + 1 in mapM_ func aList
...
return aValue
前と同じようにfunc、式の内部にのみ表示されletます。この場合は、その後の単一の式であり、他の場所には表示されません。