Real World Haskell 第3章 Defining Types, Streamlining Functions
The Offside Rule and Whitespace in an Expression Haskell の仕様で唯一不満なところが、コードのインデントのルールであるこのオフサイド・ルールだ。ルールが複雑で、なかなか頭に入らないし、長大なインデントを全部 whitespace で記述しないといけない事が多い。 あとで本文の説明に従って調べていくが、最初に言っておきたいことは、Haskell のコードのインデントに tab は使えないということだ。ファイルの行の左端からの whitespace の個数が意味を持ってしまうため、インデントに tab は使えない。長いインデントでも全て whitespace で記述しないといけない。 また、本文にはないが、オフサイド・ルールの大原則として、右にインデントしている行は上の行につながっていると考えるというのがある。 Haskell の関数の定義は基本的に1行の a single statement だ。しかしそのまま横に伸ばしていくと後で読んだり編集したりするのが大変だ。そこで、関数の定義の先頭から whitespace 1個以上右にインデントしている場合は1行が連続していると考えるのだ。次の例はインデントがバラバラだが、ひとつの行としてつながっていると考えることができる。 foo = "this is an " ++ "example of " ++ "folding of the line." 実行例 *Main> foo "this is an example of folding of the line." 第2の大原則は、関数の定義の先頭に whitespace がある場合、折り返しの部分はそれより左からはじめることはできないということだ。これがオフサイド・ルールという名前の由来のような気がする。ちなみにオフサイド・ルールは Haskell に特有のものというわけではなく、Python や他のプログラム言語でも採用されている。 第3の大原則は右でもない左でもない同じ位置でインデントしている行同士は、同じブロックの異なる文であるということ。つまり、 { statement 1; statement 2 } というブロックは、 statement 1 statement 2 と書くことができるということだ。これで、インデントが右の場合、左の場合、同列の場合のルールができたのでインデントを網羅しているといえる。 それではいよいよ本文の説明を読んでみよう。本文の最初にはトップレベルの関数の定義がインデントしているときは、それに続く関数の定義は必ずそのインデントに揃えなければならないと書いてある。RWH 本文の例は次のようなものだ。 -- file: ch03/GoodIndent.hs -- This is the leftmost column. -- It's fine for top-level declarations to start in any column... firstGoodIndentation = 1 -- ...provided all subsequent declarations do, too! secondGoodIndentation = 2 これは上で述べた大原則の2にあたる。また、上の大原則3からも頷ける。トップレベルの関数の定義は全体で一つのブロックをなすと考えることもできるからだ。 RWH の本文では次に let expression と where clause で使われるオフサイド・ルールについて述べている。let キーワード や while キーワードの後にはブロックが来るが、オフサイドルールを使うと、ブロックの {} や ; を省略することができる。たとえば、 foo = let { a = 1; b = 2; c = 3 } in a + b + c は、 foo = let a = 1 b = 2 c = 3 in a + b + c と書くこともできる。let の後のブロックの item の先頭のインデントは同じ位置に揃えなければならない。また、let と in は同じ位置でインデントしている必要がある。where の場合は次のようになる。 foo = a + b + c where a = 1 b = 2 c = 3 where のあとにくるブロックを、where キーワードの直後ではなく改行とインデントをして記述しているがこういう書き方は let の場合も可能だ。 A Note About Tabs Versus Spaces このサブサブセクションでは、インデントに Tab を使うための注意が書かれている。慣れてなければ whitespace だけを使うように勧めている。 The Offside Rule is Not Mandatory このサブサブセクションでは let や where の後のブロックは { } と ; を使って書くことができるが、Haskell では余り使われないと書いてある。 Haskell のコード例には、オフサイド・ルールのために非常に長いインデントのあるものが多い。しかし、長いインデントを whitespace だけで記述するのは面倒だ。 幸いなことに、冒頭に述べた3原則を利用すると、Haskell の場合も Ruby 流に2個のスペースだけでインデントを表現できる。このブログでも紹介した。最近の Haskell の解説書を読むと、本場でもこのような2個のスペースによるインデントで記述しているものが増えてきている。 最初からオフサイド・ルールを意識して長いインデントを作ってしまうよりは、2個のスペースのインデントで記述して、コンパイルが通らなかったら再考するというやり方でもうまくいくようだ。
by tnomura9
| 2012-03-17 07:09
| Haskell
|
Comments(0)
|
カテゴリ
新型コロナウイルス 主インデックス Haskell 記事リスト 圏論記事リスト 考えるということのリスト 考えるということ ラッセルのパラドックス Haskell Prelude Ocaml ボーカロイド 圏論 jQuery デモ HTML Python ツールボックス XAMPP Ruby ubuntu WordPress 脳の話 話のネタ リンク 幸福論 キリスト教 心の話 メモ 電子カルテ Dojo JavaScript C# NetWalker ed と sed HTML Raspberry Pi C 言語 命題論理 以前の記事
最新のトラックバック
最新のコメント
ファン
記事ランキング
ブログジャンル
画像一覧
|
ファン申請 |
||