趣味でやる Haskellλ 門 1 ~ 基礎文法編 ~ hiruishi

Similar documents
Microsoft Word - CygwinでPython.docx

第8回 関数

Functional Programming

Functional Programming

メソッドのまとめ

第12回 モナドパーサ

3.Cygwin で日本語を使いたい Cygwin で以下のコマンドを実行すると それ以降 メッセージが日本語になります export LANG=ja_JP.UTF-8 これは 文字コードを日本語の UTF-8 に設定することを意味しています UTF-8 は Cygwin で標準の文字コードで, 多

ポインタ変数

PowerPoint Presentation

スライド 1

Si 知識情報処理

ガイダンス

Microsoft PowerPoint - prog03.ppt

Java講座

プログラミング実習I

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

数はファイル内のどの関数からでも参照できるので便利ではありますが 変数の衝突が起こったり ファイル内のどこで値が書き換えられたかわかりづらくなったりなどの欠点があります 複数の関数で変数を共有する時は出来るだけ引数を使うようにし グローバル変数は プログラムの全体の状態を表すものなど最低限のものに留

メソッドのまとめ

C#の基本

PowerPoint プレゼンテーション

ToDo: 今回のタイトル

Functional Programming

ソフトウェア基礎 Ⅰ Report#2 提出日 : 2009 年 8 月 11 日 所属 : 工学部情報工学科 学籍番号 : K 氏名 : 當銘孔太

Cプログラミング1(再) 第2回

プログラミングA

slide5.pptx

プレポスト【解説】

このうち ツールバーが表示されていないときは メニューバーから [ 表示 (V)] [ ツールバー (T)] の [ 標準のボタン (S)] [ アドレスバー (A)] と [ ツールバーを固定する (B)] をクリックしてチェックを付けておくとよい また ツールバーはユーザ ( 利用者 ) が変更

PowerPoint プレゼンテーション

書式に示すように表示したい文字列をダブルクォーテーション (") の間に書けば良い ダブルクォーテーションで囲まれた文字列は 文字列リテラル と呼ばれる プログラム中では以下のように用いる プログラム例 1 printf(" 情報処理基礎 "); printf("c 言語の練習 "); printf

Microsoft Word - Python利用環境構築ガイド_ docx

Java Scriptプログラミング入門 3.6~ 茨城大学工学部情報工学科 08T4018Y 小幡智裕

PowerPoint プレゼンテーション

プログラミング入門1

これを調べるには pwd というコマンドを使います pwd とは print working directory の頭文 字をとったもので これから意味は明らかですよね 演習 1 (a) pwd を実行した結果を書け なお 立ち上げた直後の作業用ディレクトリのことをホー ムディレクトリ もしくは単に

プログラミングA

Microsoft PowerPoint - Borland C++ Compilerの使用方法(v1.1).ppt [互換モード]

Microsoft PowerPoint - kougi7.ppt

ポインタ変数

本チュートリアルについて 14 部構成 比較的簡単なトピックから 各回 プログラミング言語 任意 チュートリアルで 新しい内容 宿題 プログラミング演習 次の週 結果について発表 もしくは話し合いをする スライドは Python で Python, C++, Java, Perl についての質問い答

プログラミング基礎

プログラミング入門1

第10回 モジュール

fp.gby

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

Microsoft PowerPoint - ruby_instruction.ppt

基礎プログラミング2015

プログラミングD - Java

フィルタとは

PowerPoint プレゼンテーション

Microsoft PowerPoint - prog04.ppt

プログラミング入門1

Microsoft Word - no11.docx

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

Prog1_10th

Microsoft PowerPoint - 第3回目.ppt [互換モード]

基本的な利用法

Java言語 第1回

memo

スライド 1

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

Eclipse マニュアル <作成目的> Eclipse のインストール方法などを紹介したページはいろいろありますが 専門用語がわからない初心者でもわか りやすく Eclipse のインストール方法 基本操作などをまとめたマニュアル作成を目的としています <目次> 1 Eclipse のインストール

ご利用のコンピュータを設定する方法 このラボの作業を行うには 事前設定された dcloud ラボを使用するか 自身のコンピュータをセットアップします 詳細については イベントの事前準備 [ 英語 ] とラボの設定 [ 英語 ] の両方のモジュールを参照してください Python を使用した Spar

PowerPoint プレゼンテーション

スクールCOBOL2002

(2) 構造体変数の宣言 文法は次のとおり. struct 構造体タグ名構造体変数名 ; (1) と (2) は同時に行える. struct 構造体タグ名 { データ型変数 1; データ型変数 2;... 構造体変数名 ; 例 : struct STUDENT{ stdata; int id; do

デジタル表現論・第6回

+ Octopress + GitHubPages でブログを作成 Name: さりんじゃー

kantan_C_1_iro3.indd

ゲームプログラミング講習 第0章 導入

※ ポイント ※

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

情報工学実験 C コンパイラ第 2 回説明資料 (2017 年度 ) 担当 : 笹倉 佐藤

Boost.Preprocessor でプログラミングしましょう DigitalGhost

2

プログラミング入門1

Microsoft PowerPoint - kougi4.ppt

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

JavaScriptで プログラミング

コードテンプレートフレームワーク 機能ガイド 基礎編

プログラミング入門1

デバッグの工夫

PowerPoint Presentation

JavaプログラミングⅠ

プログラミング基礎I(再)

JavaプログラミングⅠ

Java プログラミング Ⅰ 7 回目 switch 文と論理演算子 条件判断文 3 switch 文 switch 文式が case の値と一致した場合 そこから直後の break; までを処理し どれにも一致しない場合 default; から直後の break; までを処理する 但し 式や値 1

4 分岐処理と繰返し処理 ( 教科書 P.32) プログラムの基本的処理は三つある. (1) 順次処理 : 上から下に順番に処理する ぶんきそろ (2) 分岐処理 : 条件が揃えば, 処理する はんぷく (3) 反復処理 : 条件が揃うまで処理を繰り返す 全てのプログラムは (1) から (3) の

PowerPoint プレゼンテーション

引き算アフィリ ASP 登録用の日記サイトを 作成しよう Copyright 株式会社アリウープ, All Rights Reserved. 1

講習No.1

Microsoft PowerPoint - CproNt02.ppt [互換モード]

概要 プログラミング論 変数のスコープ, 記憶クラス. メモリ動的確保. 変数のスコープ 重要. おそらく簡単. 記憶クラス 自動変数 (auto) と静的変数 (static). スコープほどではないが重要.

第1章 ビジュアルプログラミング入門

Microsoft PowerPoint - lec10.ppt

Microsoft PowerPoint - kougi6.ppt

Microsoft PowerPoint - 11.pptx

計算機プログラミング

Transcription:

趣味でやる Haskellλ 門 1 ~ 基礎文法編 ~ hiruishi

Haskell の雑な紹介 バグらずに沢山の機能を表現できるよ! というか ( 慣れたら ) ほかの言語で書くより簡潔に書けるよ!

プログラミングやったことのない人向け情報 Windows の人はスタートメニューから Windows PowerShell Mac や Linux の人は App メニュー辺りから 端末 だとか ターミナル だとかを起動してください 左側に今いるディレクトリ (Windows だとフォルダ ファイル閲覧してる時と同じ ) があるので cd ( ディレクトリ名 ) で移動 ls で今いるディレクトリのファイルを一覧表示します とりあえずこれから示すコマンドなどは cd Documents とか実行してから行うと無難です ( コマンドやディレクトリの名前は Tab キーで補完できるのでバンバン押してください ) 一個上のディレクトリに戻るときは cd../ で戻れます ついでに書いておくと 関数 f(x) の x のことを引数 ( ひきすう ) といいます

環境構築 stack( コンパイラと外部パッケージの管理 ) intero( テキストエディタに作用してエラーとか表示するやつ ) ghci( 対話モード ) の三つをセットアップします

環境構築 1 --Mac で Homebrew が入ってる -- brew install haskell-stack ; stack install intero ; stack ghci 実行後に Ctrl+d( または :q と入力 ) で抜けられます ( エラーが出た人は次頁 ) --Linux または Homebrew の入っていない Mac-- curl -ssl https://get.haskellstack.org/ sh ; stack install intero ; stack ghci 上と同様の方法で抜けられます (Mac でエラーが出た人は次頁 ) --Windows-- https://docs.haskellstack.org/en/stable/readme/#how-to-install から 64bit インストーラをダウンロードしてインストールしたのち powershell またはコマンドプロンプトにて stack install intero ; stack ghci を実行 初回セットアップが終わったら上二つと同様の方法で抜けられます

環境構築 2 macでxcodeのエラーが出る人は xcode-select --install を実行してください その他詳細は https://docs.haskellstack.org/en/stable/install_and_upgrade/ を参照してください

エディタの拡張 VisualStudioCode なら Haskero または Haskelly プラグインを導入 emacs なら Intero for Emacs (https://haskell-lang.org/intero 2019/02/25 リンク更新 ) の 指示に従って.emacs を編集 ( またリンク切れるかもしれないので次頁参照 ) ( 初回セットアップが終わったら追加部分に関しては最後の一行以外コメントアウトしても大丈夫っぽい ) vim の人は https://github.com/fyrbll/intero-vim,neovim の人は https://github.com/parsonsmatt/intero-neovim からプラグインを導入

emacs の補足 Mac, または Linux についてはホームディレクトリの.emacs に以下を追記 ;; If you don't have MELPA in your package archives: (require 'package) (add-to-list 'package-archives '("melpa". "http://melpa.org/packages/") t) (package-initialize) (package-refresh-contents) ;; Install Intero (package-install 'intero) (add-hook 'haskell-mode-hook 'intero-mode) 初回起動時以降は最終行以外の行頭に ; を付ければ起動が早くなりますemacs については基本マウスで操作しながら F10 キーでメニュー Ctrl+x のあとに Ctrl+s で保存 Ctrl+x のあとに Ctrl+f でファイルを開く Ctrl+x のあとに Ctrl+c で抜ける Alt+w でコピー Ctrl+y で貼り付けができるって覚えていけばとりあえず困らないよ

最小限の構成 適当な場所に拡張子が.hs のファイルを作ります ( 文字コードは utf-8) 今回は Basic.hs で作ったとします ( ファイル名の頭文字は必ず大文字!) そのディレクトリにて stack ghci Basic.hs を実行すると対話モードで Basic.hs の内容をテストすることができます

なんで Hello,world! しなきゃいけないんですか? 試しに 1 + 1 と入力してみましょう Main>1 + 1 2 stack ghciを電卓代わりにも使える ( 少なくとも筆者は使う ) stack ghci ( ファイル名を指定しないで実行もできる ) Prelude> 1 + 1 * 2 3

文法基礎編 型の定義と関数の定義で 1 セット! ( とはいえ型の定義は省略も可能 ) foo :: Int -> Int -- 型シグネチャ foo x = x + 1 -- 関数の定義 Haskellの場合 型は単なる記憶領域確保のためのものではなく 数学における 集合 と同じような意味を持つ( 写像の始域と終域 覚えていますか?) ちなみに関数名は必ず小文字から 型の名前とファイル名は必ず大文字から! ( 型や変数 ファイル名もすべてキャメルケースで書きましょう ) CamelCase や camelcase のように単語の区切りを大文字にして区切ってください

コメント -- と書くとそれより右側はコメント扱いになり メモとしていろいろ書いてもエラーにならない {- と -} で挟んでも良い この場合は複数行を一度にコメント扱いできる foo x = x + 1 -- コメントをここに書く {- ここにもコメントを書くことができる 関数の役割のメモなどにどうぞ -}

Basic.hs foo :: Int -> Int foo x = x + 1 const1 :: Int -- 定数関数 const1 = 1 この内容を書き終えたらghciで :r を実行して再読み込み foo 2 や foo const1 を実行してみましょう ( 引数を括弧でくくる必要はない!)

インデント ( 字下げ ) について python と同じくインデントの深さで範囲 ( 例えば関数の定義を何行にわたって書いているか C 言語でいう {}) が決定されるので必ず Tab キーや Space でインデントを入れましょう ちなみに通常の関数定義は字下げの深さ 0 です foo :: Int -> Int -- :: と -> が揃うと見やすさがアップ foo x = x + 1 foo :: Int -> Int foo x = x + 1 -- foo と 1 が同じ字下げ ( この場合深さ 0) だとエラーになる ちなみに Emacs の intero だと Tab キー押せば一発でそれっぽいインデントにしてくれる (VSCode だとなぜかできなかった )

ghci の使い方 :t で型を見ることができる Main> :t foo Int -> Int Main> :t foo 1 Int Main> :t const1 Int

ghci の使い方 :i で型や関数の定義を表示 ( このスライド中のわからない要素も :iや:tで調べましょう) Main> :i Int Main> :i map :q( またはCtrl+d) でghciを終了 :h でヘルプちなみに変数名や型名はTabキーで補完できます :l ( ファイル名 ) で読み込み

ghci の使い方 おまけ いざ ghci で何か関数を定義したとき 型の定義を入れたらエラーになったと思います そういうときは複数行定義の記号を使って :{ ( 型の定義 ) ( 関数の定義 ) :} とするとよいです

関数を引数に取る関数とか Main> :t map (a -> b) -> ([a] -> [b]) (aやbのように小文字で始まる型は 任意の型 という意味) 1 変数関数を引数に取り リストからリストへの関数 にしてくれる Main>:t map foo [Int] -> [Int] ([Int] でIntのリストという意味 ) Main> map foo [1,2,3,4,5,6] ( ちなみに map foo [1.. 6] という書き方もOK!) これってなんか 2 変数関数みたいじゃね?

2 変数関数 3 変数関数 bar :: Int -> Int -> Int bar x y = x + y bar 1 2 のように書く ちなみに内部的には bar 1 :: Int -> Int の関数が生成した後 (bar 1) 2 :: Int と関数が適用され 最終的にInt 型の値が出てくる ( カリー化による部分適用 ) 3 変数関数も同じ理屈 まぁ正直 bar :: Int -> Int -> Int の 前二つの Int が引数の型で 最後の Int が関数の戻り値って覚えておいてもそんなに困らないけどな!

2 変数関数おまけ bar 1 のように要求されているよりも少ない引数を渡すと残りの引数を引数としてとる関数になる ( この場合 Int -> Int) (bar 1) 2 で 3 になる 二項演算子もこの規則が適用されるので (+ 1) と書けば +1 してくれる無名関数になる Main> (+ 1) 2 3 ちなみに関数を二項演算子にしたいときは ` ` をつかう Main> 1 `bar` 2

無名関数 前ページの通り 多変数関数の引数を不足させたものも関数の扱いになる Main> (bar 1) 2 Main>:t (+) Main> (+) 1 2 ラムダ式によって無名関数を作ることもできる bar2 :: Int -> Int -> Int bar2 = \x y -> x + y -- \x y -> x + y がラムダ式 1 変数なら \x -> x + 1 とか

データ型 ( 直積型 あるいはデカルト積型 ) 直積集合は高校でやる積集合とは違うから気を付けてね! data NingenSama = NingenSama -- こっちは型コンストラクタ -- ややこしいけどこっちはデータ ( 値 ) コンストラクタ { age :: Int, name :: String } deriving Show --この行はghciで画面に表示するのに必要 NingenSama 10000 akachan とするとNingenSama 型の値になる

直積型のおまけ age は NingenSama -> Int の関数になる nameは NingenSama -> String の関数 age $ NingenSama 10000 akachan $ は文末までの括弧と同じと思ってよい ( 本当は違うけど ) ちなみにageやnameを省略して data NingenSama = NingenSama Int String deriving Show とやってもよいが 当然あったほうが便利だし何やってるかわかりやすい ( データコンストラクタ NingenSama の引数部分には定義の時には型を書くけど実際呼び出すときには値を書くから混乱するよ! 気を付けてね )

データ型 ( 直和型 ) data Tensuu = TensuuSuuji Int NanrakanoJiko String deriving Show TensuuSuuji 98 も NanrakanoJiko report hyousetsu ga bare ta も同じTensuu 型 直和型と直積型を組み合わせればいろいろ作れる data Zoo = Animals Int String UchuKaraKitaAlien ZooT Tensuu ZooN NingenSama

いろいろやってみましょう NingenSama 型や Tensuu 型を Basic.hs にて定義し ghci で動作を確認してみましょう (:r で再読み込み ) 余談 型に別名を付けるだけならデータ型を使わず type を使う 実際の例 : type String = [Char]

標準で定義されているデータ型 タプル (a,b) -- a と b は任意の型 (1, abc ) などの値が作れる リスト (a は任意の型 ) data [a] = [] a : [a] : という二項演算子のデータコンストラクタが定義されていて 先頭から追加できる 例えば [1,2,3,4,5] は 1:2:3:4:5:[] と同じ Maybe a 型 Maybe a = Just a Nothing a は任意の型 エラー処理に使ったりする Maybe Int なら Int が入っている (Just 1 など ) かもしれないが エラーにより何も入っていない (Nothing) かもしれない という用法 ユニット型 () という型で () という値しか入らない ほかの言語における void 型と同じ使い方をするけど 本来の意味は違う

分岐処理 if 文 baz :: Bool -> Int baz b = if b then 1 else 0 ( なんかあんまり使った記憶がない 後述のガード文のほうが便利 )

分岐処理 ガード文 ( 数学で見たことあるやつ ) relu :: Int -> Int -- ニューラルネットワークの活性化関数として使われる relu x x < 0 = 0 otherwise = x otherwiseはghciで調べるとtrueと同じ意味 なので上の行でマッチしなかったらここで必ずマッチする

分岐処理 パターンマッチ ( データ型を利用した分岐とかに使える ) anzen :: Zoo -> Bool anzen z = case z of ZooN (NingenSama a n) -> if a > 10000 then False else True _ -> False nは定義したけど使わなかったので _ ( ワイルドカードパターン ) を使って ZooN (NingenSama a _) -> みたいに書くとよい ( 中の値はメモリから消される ) case 文の条件に適当な変数名や _ を持ってくると必ずマッチするので この場合 NingenSama a nにマッチしなかったら必ず Falseになる

分岐処理 ( 併用 ) パターンマッチとガードの併用 ( さっきは if 文と併用したけど ガードで書き直してみる ) anzen :: Zoo -> Bool anzen z = case z of ZooN (NingenSama a _) -- ワイルドカードパターンのところは使わない a > 10000 -> False --ガードとの併用 otherwise -> True _ -> False -- ガードを併用しないとき

分岐処理例題 データ型 data Zoo = Animals Int String UchuKaraKitaAlien deriving Show が与えられているときに anzen 関数 (anzen :: Zoo -> Bool) を自分で定義してみましょう if 文は使わなくていいけど パターンマッチ (case 文 ) とガード文は必ず使いましょう ( は定義が被らないようにつけたけど Basic.hsにさっきのZooの定義を書いてなかったらつけなくていいよ ) ( ていうかふつうは anzenじゃなくてissafeとかのほうがわかりやすい気がする )

再帰による繰り返し処理ここから 2 つの例題については後で述べる参考文献を参照 factorial :: Integer -> Integer factorial = go 1 Int 型はほかの言語同様上限と下限があるが Integer にはない ちなみに factorial は 階乗 な where -- 局所定義 ここに書いた関数 goはfactorialの定義以外で参照できない go a n n <= 0 = a otherwise = go (n * a) (n - 1) goの第一引数は蓄積引数といって 現時点での正しい計算結果を記憶する

再帰による繰り返しとリスト Basic.hsの先頭に import Data.Char (digittoint) を追加してください digittoint :: Char -> Int Main> digittoint a

再帰による繰り返しとリスト - 前提知識 文字列型 String は Char のリスト [Char] と同じ [Char] 型の値は [] または a : b : c : : [] ( これを [a,b,c,,z] と書く ) ( ただし変数 a,b,c,... には何か文字が入っているとする ) 例えば文字列 abc (=[ a, b, c ]) は a : b : c : [] 遅延評価 (take 関数はリストの先頭から指定した数だけ持ってくる ) take 10 [1.. ] のように無限リストを使った式でも リストの中身は要求されるまで生成されないのでメモリがいっぱいになったりしない なんでこんなめんどくさい定義になってるかというと 遅延評価をしたいから

再帰による繰り返しとリスト 16 進数の数値を表す文字列を数値 ( 数値 ) に直す関数 readhex を作ってください readhex :: [Char] -> Int readhex = undefined -- undefinedと書くことで定義をまだ書いていない関数について エラーを出さないようにできる ヒント : さっきの facotrialを参考に ヒント : 変数 xxsに [Char] 型の値が入っている場合のパターンマッチ case xxs of x : xs -> undefined -- xはxxsの先頭 (Char 型 ) xsはその残り ([Char] 型 ) [] -> undefined -- リストが空っぽ つまり全部評価し終えた時の処理

補足 :undefined について 前頁に書いた通り undefined と書くとまだ定義されていない部分についてエラーを出さないままにできる ( ただしそのまま放っておくと実行時にエラーになる )

畳み込み関数を使った繰り返し Main> :t foldl foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b foldl :: (b -> a -> b) -> b -> [a] -> b として使うことができる (Foldable については次回やります ) foldl ( 今の値と新情報による更新処理 )( 初期値 )( 新情報のリスト ) みたいに使う readhex :: String -> Int を foldl を使って定義してみましょう

参考文献 haskell-tiny-intro ( マイコンクラブOBの人が書いた教材 ) https://github.com/khibino/haskell-tiny-intro/blob/master/exercise/basic.hs baz factorical と readhex の例題等ここから持ってきました すごいHaskellたのしく学ぼう! オーム社めちゃんこ分厚いけどわかりやすいと評判の本 私はちょっとしか読んでないけど

次回予定 趣味でやるHaskell2 ~ 実用編 ~ hoogleを使ってみよう 型クラス 入出力と逐次処理 リストによるループ処理の簡略化などTips プロジェクトの立ち上げとビルド 外部パッケージの導入 代表的なパッケージの紹介