第10章 型とクラスの定義 #8

10.8 練習問題 以下のインスタンス宣言を完成させよ。 instance Monad Maybe where ... instance Monad [] where ... ここで[]は、[a]から型変数を取り除いたリスト型を表す。 ヒント:最初に、それぞれのインスタンスのメソッド return と >>= の型を考えよ…

第10章 型とクラスの定義 #7

10.8 練習問題 関数 isTaut と、前の二つの章で定義したパーサーと対話プログラムのライブラリを用いて、対話的に恒真式か検査する関数を実装せよ。ユーザーがキーボードからわかりやすい文法で命題を入力できるようにすること。 ヒント:8章で定義した数式…

第10章 型とクラスの定義 #6

10.8 練習問題 再帰と関数addを用いて、自然数の乗算関数 mult :: Nat -> Nat -> Nat を定義せよ。 これは楽勝。(10.3で定義したNatはゼロも自然数だったことを思い出して) module TenEightOne where import TenThree mult :: Nat -> Nat -> Nat mult Zero…

第10章 型とクラスの定義 #5

10.6 クラスとインスタンスの宣言 前にも書いたけど、Haskellのクラスは型クラスで、型クラスのインスタンスは型。 最初はBool型がEqクラスを実装する例。自分でも手を動かしたかったので、Bool型とEqクラスを自分で定義してみる。演算子はちょっと悩んだけ…

第10章 型とクラスの定義 #4

10.5 仮想マシン 二つ目の長い例題として、整数と加算演算子からなる単純な数式の型と、この数式を評価して整数にする関数を考えよう。 data Expr = Val Int | Add Expr Expr value :: Expr -> Int value (Val n) = n value (Add x y) = value x + value y …

第10章 型とクラスの定義 #3

10.4 恒真式 命題論理式を表す型を作り、与えられた命題が恒真式(式に含まれる変数の値に関係なく、常に真となる式)かどうかを判定する関数を書く。 まずは命題の型を定義。 真理値(True, False)Const Bool 変数(A, B, ... , Z)Var Char 否定(¬)Not Prop …

第10章 型とクラスの定義 #2

前回の日記でdataによる型定義を学んだけど、これ、もっと掘り下げておくべきだったな。 引数なしのデータコンストラクタだと列挙型みたいなもの。これはOK。たとえば、Bool型の要素がTrueとFalse、といった形でこれまでも登場している。 でも引数ありのデー…

第10章 型とクラスの定義 #1

10.1 typeによる型宣言 typeキーワードは型のエイリアスに名前をつける方法。再帰定義はできない。 type Assoc k v = [(k,v)] find :: Eq k => k -> Assoc k v -> v find k t = head [v | (k',v) <- t, k == k'] newtypeキーワードは教科書に出て来てないな…

第9章 対話プログラム #9

9.9 練習問題 練習問題5は「グラフィック・ライブラリを用いて」とか書いてあって面倒なのでパス。Windowsで動かなかったりするし。 ニムはボードを使うゲームである。ボードには、番号の付いた行が五つあり、はじめは星が以下のように並べてある。 1:***** …

第9章 対話プログラム #8

9.9 練習問題 ライフゲームのボードを対話的に作成したり、変更したりできるエディターを作れ。 9.7で写経したライフゲームを修正して、ボードサイズを可変にできるようにしてやったぜ。 module NineNineFour where import System.IO import NineFive getCh …

Re: Haskell vs F#

http://d.hatena.ne.jp/rst76/20120204/1328362118 F#の環境を作るのが面倒という声も上がっているけど、 オンラインでやりゃいいじゃない。パンがなければお菓子を食べればいいじゃない。 というか、Linux/Mac/Solarisな人ならmonoを入れれ。 http://www.go…

第9章 対話プログラム #7

9.9 練習問題 ライフゲームは、世代ごとに画面全体をクリアするので、動かす環境によっては、動きがちらつくかもしれない。それを防止するために、状態が変わったところだけ表示し直すようライフゲームを変更せよ。 うーん。リモートターミナルとかだとちら…

第9章 対話プログラム #6

9.9 練習問題 エラーの際に単にビープ音を鳴らすのではなく、エラーの位置が分かるように電卓を変更せよ。パーサーは消費しなかった文字列を返すという性質を活用するとよい。 「エラーの位置がわかるように」というのが何を求めているのかよくわからないが…

第9章 対話プログラム #5

では実際に解いてみよう。 9.9 練習問題 アクション getLine に、削除キーで文字を消去できる機能を加えたアクション readLine :: IO String を定義せよ。ヒント:一文字削除するための制御文字は "\DEL"、一文字戻るための制御文字列は "\ESC[1D" である。 …

ターミナル

さて、getChの前から怪しいと思ってたのだけど、getCharがEnterを押すまでキーを認識しない。 いろいろ調べると、バッファリングモードの問題らしく import IO do hSetBuffering stdio NoBuffering とかなんとかそういうのをやれと書いてある。が、やっても…

第9章 対話プログラム #4

9.9 練習問題 今日は時間がないので、問題文を写すだけにしておく。 アクション getLine に、削除キーで文字を消去できる機能を加えたアクション readLine :: IO String を定義せよ。ヒント:一文字削除するための制御文字は "\DEL"、一文字戻るための制御文…

木探索とCPS

もともと、俺のHaskell学習の目標は、“http://d.hatena.ne.jp/rst76/20100706/1278430517を全部理解できるようになること”だったわけで、それは今でも変わっていない。 で、Haskellはだんだんわかって来たけど、“木探索から CPS にすることで効率化”が腑に落…

第9章 対話プログラム #3

ライフゲーム さて、9.7はライフゲームの実装。 ひたすら写経。9.5で実装した関数群を使っている。 module NineSeven where import NineFive width :: Int width = 5 height :: Int height = 5 type Board = [Pos] glider :: Board glider = [(4,2), (2,3), …

getCh

9.6の計算機プログラムの中でgetChという関数が出てきていて、コンパイルに通らないのでgetCharに置き換えてたんだけど、 Hugs, but can be defined in Haskell as follows: >|haskell| import System.IO getCh :: IO Char getCh = do hSetEcho stdin False …

第9章 対話プログラム #2

というわけでminttyからhugsを起動する方法にしたら捗った。 あと、今までは全部1ファイルでやろうとしていたが、色々無理が出てきたのでモジュール化した。 module NineSix where import Parsing import Expr import NineFive box :: [String] box = ["+---…

Windowsでもいいや

MSYS上のminttyからhugsを起動すればいいということで、今後はそうする。

F#のつまみぐい

F#

Haskellにくわしい後輩から「F#教えてください」と言われたが、俺もわからんのよ。F#のコードを書いたことがないので。 でもそれじゃつまらないので、Haskellの勉強で学んだ知識をもとにF#に挑戦してみた。 いろいろ試行錯誤した結果がこれだ。One, Two Thre…

WinHugsはやめる

そういえばうちにはMac Miniがあったんだった。ずっとWindowsばかり起動していたから忘れていた。 てなわけでMacPortsをインストールした後Hugsをインストール。Windowsからはteraterm経由でアクセス。 おお、快適。エスケープシーケンスも動くし。

生きてます

IOモナドで計算機はいいんだけどさあ。Windowsではちょっとねえ。前回書いたように、エスケープシーケンスは動かないし、グラフィクスライブラリ(HGLとかSOEとか)は動かないし。やる気が…… VirtualBoxかなにかでUbuntuとか動かして、そこでHaskellをやるか………

第9章 対話プログラム #1

仕事が忙しくて書けてなかったけど、忘れたわけではない。 入出力の型 IO aの簡易説明、っていうかこのWorldを使った説明はごまかしだよなあ。 写経したコードを試しに実行する時に困るんだよねえ。 カリー化によって(最近、ScalaやGroovy界隈で話題だった…

本物のモナドで第8章

教科書の第9章をパラパラと読んだら、第9章はIOモナド。しかも第8章のパーサーを使用するようだ。 てことは、第8章のパーサーを本物のモナドで定義しておかないと、サンプルコードを実行できないと思われる。 仕方なく、教科書のサイトから第8章のパーサーを…

第8章 関数型パーサー #7

演習問題 問題7 累乗を定義。 term' :: Parser Int term' = pow >>- \p -> (symbol "*" >>- \d -> term' >>- \t -> return' (p * t)) +++ (symbol "/" >>- \d -> term' >>- \t -> return' (p `div` t)) +++ return' p pow :: Parser Int pow = factor >>- \f…

第8章 関数型パーサー #6

演習問題 問題6 おれおれbindとreturnで。 expr' :: Parser Int expr' = term' >>- \t -> (symbol "+" >>- \d -> expr' >>- \e -> return' (t + e)) +++ (symbol "-" >>- \d -> expr' >>- \e -> return' (t - e)) +++ return' t term' :: Parser Int term' =…

第8章 関数型パーサー #5

演習問題 問題4 expr | term ______|________ | | | factor * term | _____|___ nat | | | | factor * term 2 | | nat factor | | 3 nat | 4 expr | term ___________|_____ | | | factor * term _______|________ | | | | factor ( expr ) | ____|____ nat …

第8章 関数型パーサー #4

旅行に行ったので間があいてしまった。 数式 相変わらずdo記法を使わずにオレオレbindとオレオレreturnで書いてみる。 expr :: Parser Int expr = term >>- \t -> (symbol "+" >>- \d -> expr >>- \e -> return' (t + e)) +++ return' t term :: Parser Int …