- Haskellをやり始めると、「できるようになろうよ」というチュートリアルや、「数学的にはこうで…」というチュートリアルにばかり行き着く…
- 、のですが、コードを読んだり書いたりするためにはsyntaxとかlexica(lexicon)とかの情報が少なすぎてつらい…
- 結局、こちら(haskell2010.pdf)を見ることに。
- 2.1 Notational Conventions
- で、いきなりパターンマッチから始まって困るわけですが、書き方は以下のルールで記載します、とのこと
[ hoge ] : あってもなくてもよい、オプショナル
{ hoge } : hogeの繰り返し
( hoge,hige ) : hogeやhigeのグループ・集まり
hoge | hige : hogeまたはhige
hhhhh_{kkkk} : hhhhのこと、ただし、kkkkは除く
- 2.2 Lexical Program Structure
- 次に、Haskellのプログラム、とにかく、こう書く、というのが、また、パターンマッチで書いてあるのですが、ここまで慣れてくると、まあ、こう記載するのが正しいし、こうしか説明できないなぁ、と納得する書き方になっていて
- 確かに、ちゃんと書いてあります。当たり前ですが
- そして、Haskellのプログラムコードで、定義が後ろに来てもよいことになっているのと同じで、この仕様書でも、未定義用語が出てきて、その定義が後に出てくることも頻出するので注意。PDFファイルで検索を使えば、ちゃんと出てきます
- プログラムは、lexeme または whitestuffを0個以上繰り返したもの
{lexeme | whitestuff}
-
-
- 大概のプログラムはそうですね。確認するべきは、lexemeが何で、whitestuffが何か、なわけですが
- whitestuffは空白文字で出来たものか、コメントとして定義されたもの
- lexemeはwhitestuffではないもの。ただし、使えるものは限定されます
- lexeme:いわゆるコードの本体として定義されているものは、と言えば
qvarid
qconid
qvarsym
qconsym
literal
special
reservedop 予約演算子
reservedid 予約ID
-
-
- これさえ解れば、よいことがわかります
- これらを分類すると
- IDとオペレータとリテラルと特別記号の4つに別れます
- IDは英単語的に書かれるもの
- オペレータは演算記号のように書かれるもの
- リテラルは、「そのまま意味があるもの」
- 特別記号は区切りを意味するものなど
- IDに含まれるのはqvarid, qconid, reservedid
- オペレータに含まれるものはqvarsym, qconsym, reservedop
- リテラルにふくまれるのはInteger, Float, Char, String
- 特別記号に含まれるのは
(
)
,
;
[
]
`
{
}
-
-
- "qhoge"
- "qhoge"が4つありますが、この"q"は"qualifiedの"q"。「コードの文脈で紛れなく理解可能な」という意味。紛れがなければ、qなしのvarid,conid,varsym,consymでよいし、紛れが無いようにmodule.varidのように名前空間制御してあってもよいことを指します
- ID : 英単語のように書かれるもの
- 小文字始まりはvariableIDと予約ID
- 大文字始まりはconstructorID
- 演算子 : 記号で書かれるもの
- ":" 以外で始まる variableSymbol
- ":"で始まる constructorSymbol
- 予約演算子
.. 列挙 [1..5]とか
: リストを分ける x:xs
:: 型宣言
= 関数宣言
\ (back slash) ラムダ関数
| または、場合分け、内包表現の条件宣言
<- ...の要素である
-> 関数の型の推移
@ パターンマッチしながら、全部を使いたいとき var@pat
~ …に関わらず(真、とか)
=> 型宣言における文脈宣言
-
- いろいろな「記号」が定義されて使われている。それの一覧はこちら
- 予約単語は以下の通り
case
class
data
default
deriving
do
else
foreign
if
import
in
infix
infixl
infixr
instance
let
module
newtype
of
then
type
where
_
-
- これらのうち、主に関数の内容を宣言する"expression"のための予約語は、"if...then...else", "case...of" "let...in"。また、予約単語ではないが、関数のための"\ (back-slash)"も関数内容宣言のための予約文字である
- 新たにIDを作るための予約単語に、"type", "newtype", "data", "class"がある。タイプ(型)の作成のために"type","newtype","data"が用意されているのは、わかりにくい面もあるが、タイプ作りは頻繁に行われるからであって、なるべく効率よく作りたいから、と思って、飲み込むことにする
- "class"を作るとして、それは抽象的なので、その実体を個別に作るために"instance"が用意されている
- "where"は条件付けをする場合に使うが、あちこち(関数の内容宣言でも使うし、classのinstance宣言でも使うし、moduleの中身を示すのにも使う)
- infix,infixl,infixrは中置演算子の定義のときに使う。中置演算子は演算に向き無し、向き有り(どちら向き)、を指定するために3つある
- moduleは、そういう実体があるので、それを表す
- do構文は、Haskellの中で唯一、順番に意味を持たせる特別な構文のための印
- deriving はクラスの「継承」のようなものの宣言
- default・・・(わからない)
- "_"はワイルドカード
- その他のまとめ
- その他
- fmap ($x) f というのは、xを引数として関数を掛けるという動作をせよ、という意味。その後ろでfを取っているので、関数 fがxに掛かる(こちら)