「48時間でSchemeを書こう」の版間の差分

削除された内容 追加された内容
→‎Return Values: 一部訳出
→‎戻り値: 一部訳出
290 行
# <code>Bool</code> - Haskellの真偽値を保持します。
 
コンストラクタと型は別々の名前空間を持つので、Stringという名前のコンストラクタとStringという名前の型両方を併存させることができます。型とコンストラクタタグは常に大文字から始まります。
Constructors and types have different namespaces, so you can have both a constructor named String and a type named String. Both types and constructor tags always begin with capital letters.
 
次に、これらの型を持つ値を作るパーサ関数をいくつか加えましょう。文字列は、二重引用符で始まり、それに引用符以外の文字が0個以上続き、二重引用符で閉じられます。
Next, let's add a few more parsing functions to create values of these types. A string is a double quote mark, followed by any number of non-quote characters, followed by a closing quote mark:
 
<syntaxhighlight lang="haskell">
parseString :: Parser LispVal
parseString =:: doParser char '"'LispVal
parseString ::= Parserdo LispValchar '"'
x &lt;- many (noneOf "\"")
x char<- 'many (noneOf "\""')
char return $ String x'"'
return $ String x
</syntaxhighlight>
 
We're back to using the また>>演算子の代わりにdo-notation instead of the &gt;&gt; operator. This is because we'll be retrieving the value of our parse 記法を使っています。これは私たちがパース結果の値(returned by <code>[http://www.cs.uu.nl/~daan/download/parsec/parsec.html#many many] ([http://www.cs.uu.nl/~daan/download/parsec/parsec.html#noneOf noneOf] "\"")</code>によって返される) and manipulating it, interleaving some other parse operations in the meantime. In general, use &gt;&gt; if the actions don't return a value, &gt;&gt;を取り出し、他のパース関数を間に挟みながら操作することになるからです。一般に、アクションが値を返さないときに<code>>></code>を、値をすぐに次のアクションに渡すときに<code>>>= if you'll be immediately passing that value into the next action, and </code>を、その他の場合にdo-notation otherwise.記法を使います。
 
一旦パースし終わり<code>many</code>からHaskellの文字列が返ってきたら、(<code>LispVal</code>データ型の)<code>String</code>コンストラクタによってそれを<code>LispVal</code>にします。全ての代数的データ型のコンストラクタは引数をその型の値に変える関数のような働きをします。それは[[#簡単なパーサ]]でパーサを<code>Either</code>データ型の二つのコンストラクタに対してマッチさせたときのように、パターンマッチングの左辺で使えるパターンとしても機能します。
Once we've finished the parse and have the Haskell String returned from <code>many</code>, we apply the String constructor (from our LispVal data type) to turn it into a LispVal. Every constructor in an algebraic data type also acts like a function that turns its arguments into a value of its type. It also serves as a pattern that can be used in the left-hand side of a pattern-matching expression; we saw an example of this in [[#Writing a Simple Parser|Lesson 3.1]] when we matched our parser result against the two constructors in the <code>Either</code> data type.
 
その後<code>LispVal</code>をParserモナドにするのにビルトイン関数[http://www.haskell.org/onlinereport/standard-prelude.html#$tMonad return]を適用します。doブロックのそれぞれの行は同じ型を持たなければなりませんが、<code>String</code>コンストラクタの結果はただの<code>LispVal</code>です。<code>return</code>はそれを包み上げ、入力を何も消費せずそれを内部の値として返すParserアクションにしてくれます。よって、<code>parseString</code>アクション全体では<code>Parser LispVal</code>という型を持つことになります。
We then apply the built-in function [http://www.haskell.org/onlinereport/standard-prelude.html#$tMonad return] to lift our LispVal into the Parser monad. Remember, each line of a do-block must have the same type, but the result of our String constructor is just a plain old LispVal. Return lets us wrap that up in a Parser action that consumes no input but returns it as the inner value. Thus, the whole parseString action will have type Parser LispVal.
 
The <code>$</code> operator is infix function application: it's the same as if we'd written 演算子は中置関数適用です。<code>return (String x)</code>, but と書いても同じですが、<code>$</code> is right-associative, letting us eliminate some parentheses. Since は右結合なので括弧を幾つか省くことができます。<code>$</code> is an operator, you can do anything with it that you'd normally do to a function: pass it around, partially apply it, etc. In this respect, it functions like the は演算子なので、引数として他の関数に渡したり部分適用するなど、関数と同様に扱うことができます。この点に於て、<code>$</code>はLisp function の関数[http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.4 apply].のように働きます。
 
Now let's move on to Scheme variables. An [http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-5.html#%_sec_2.1 atom] is a letter or symbol, followed by any number of letters, digits, or symbols: