Haskell コーディング仕様〜私のためのHaskell再入門2

  • 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"。また、予約単語ではないが、\lambda関数のための"\ (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に掛かる(こちら)