fugafuga.write

日々のログ



Haskell

すごいH本 part43

Show と Read は文字列へ変換できるもの、文字列から変換できるものの型クラス。ある型をそれらのインスタンスにしたいなら、その型の値コンストラクタにフィールドがあれば、それらの型も Show や Read に属している必要がある。 data Person = Person { fi…

すごいH本 part42

インスタンスの自動導出 型クラスはある振る舞いを定義するインターフェースである Haskell ではまずデータ型をつくり、それがどう振る舞えるかを考える 仮にその型が等値制をテストできるなら Eq型クラスのインスタンスにする 仮にその型が大小比較できるも…

すごいH本 part41

三次元ベクトルの型とベクトルの演算を作る data Vector a = Vector a a a deriving (Show) vplus :: (Num a) => Vector a -> Vector a -> Vector a (Vector i j k) `vplus` (Vector l m n) = Vector (i+l) (j+m) (k+n) dotProd :: (Num a) => Vector a -> V…

すごいH本 part40

型コンストラクタの話 data Maybe a = Nothing | Just a aが型引数でMaybeは型コンストラクタという。型コンストラクタからMaybe Int, Maybe Char, Maybe Stringなどの型を作ることができる。 Haskell には型推論があるので、たいてい明示的に型コンストラク…

すごいH本 part39

レコード構文 人物のデータ型を作る data Person = Person String String Int Float String String deriving (Show) フィールドは、名前、苗字、年齢、身長、電話番号、好きなアイスクリームの味 となっている。 人物を作成してみる *Shapes> let guy = Pers…

すごいH本 part38

Shape をShapesモジュールとしてエクスポートする module Shapes ( Point(..) , Shape(..) , area , nudge , baseCircle , baseRect ) where data Point = ... ... ... Shape(..)と書くと、Shapeの全ての値コンストラクタがエクスポートされる。後から値コン…

すごいH本 part37

データ型の続き Point データ型 二次元空間の点を表現する data Point = Point Float Float deriving (Show) data Shape = Circle Point Float | Rectangle Point Point deriving (Show) 値コンストラクタが1つしかないデータ型は、値コンストラクタ名とデー…

すごいH本 part36

新しいデータ型を自分で作る dataキーワードを使う。 標準ライブラリでのBool型の定義 data Bool = False | True 等号の前が型の名前、等号の後が値コンストラクタ 値コンストラクタは、型が取り得る値の種類のこと。 長方形と円の図形を型として表現する。 …

すごいH本 part35

階層的モジュール モジュールには階層構造を与えることができる。 Geometry.hsを分割する。Geometryディレクトリを作成する。 Geometry/Sphere.hs module Geometry.Sphere ( volume , area ) where volume :: Float -> Float volume radius = (4.0 / 3.0) * …

すごいH本 part34

今週のお題「2018年の抱負」 モジュールを作る Geometry.hs module Geometry ( sphereVolume , sphereArea , cubeVolume , cubeArea , cuboidArea , cuboidVolume ) where sphereVolume :: Float -> Float sphereVolume radius = (4.0 / 3.0) * pi * (radius…

すごいH本 part33

今週のお題「2018年の抱負」 Data.Mapの話 連想リストを使うをMapを使うということにする。Data.Mapはキーが順序付けされていることを利用して、効率よくキーを配置したりキーにアクセスしたりできる。 Data.MapはPreludeやData.Listと競合する名前をエクス…

すごいH本 part32

あけおめ。今年もHaskellやっていきます。 キーから値へのマッピング 連想リストでキーと値のペアを作成できる。 phoneBook = [("betty", "555-2938") ,("bonnie1", "334-8878") ,("bonnie2", "334-8878") ,("bonnie3", "334-8878") ,("bonnie4", "334-8878"…

すごいH本 part31

今年も終わりですね モジュールの続きをやっていく 各桁の数の合計が40になる最初の自然数を求める関数の実装 数値を文字列に変換 文字列をリスト化 文字を数に変換 リストの合計を計算 このように処理する。 Data.Char.digitToIntで文字を数値に変換する('0…

すごいH本 part30

モジュールを使う。の続き foldlがスタックオーバーフローを起こすことがあるのでそれを見てゆく。 *Main> foldl (+) 0 (replicate 100000000 1) *** Exception: stack overflow Haskell は遅延評価なので実際の値の計算は可能な限り後まで引き伸ばされる。 …

すごいH本 part29

モジュールを使う。の続き Data.Charを使ってシーザー暗号でメッセージを暗号化し、他人に読めないようにする関数を実装する。 シーザー暗号は、各文字をアルファベット上で一定の数だけシフトするという暗号化方法。 以下の関数を使う Data.Char.ord 文字を…

すごいH本 part28

引き続きモジュールの使用例 2つのリストを受け取り、1つめのリストが2つめのリストに含まれているかどうかを調べる関数を実装してゆく。 以下の関数を使う Data.List.tails リストを受け取り、tailsを繰り返し適用する *Main Data.List> tails "yahooooooo…

すごいH本 part27

モジュールを使う 単語が複数含まれた文字列から各単語が何回現れるかを求めたい。 以下のモジュールと関数を組み合わせる。 Data.Listのwords 空白で区切られた単語をリストにする。 *Main Lib Data.List> words "foo bar hoge hooogle" ["foo","bar","hoge…

すごいH本 part26

クリスマス後に4℃のアクセサリが多数オークションに出品されるのはとても趣がある。 モジュール Haskell にはモジュールがある。モジュールには複数の関数と型を定義できる。 そのモジュールのうちの幾つか、または全てをエクスポートできる。 エクスポート…

すごいH本 part25

サンタさん、5000兆円ください ポイントフリースタイル この関数を sum' :: (Num a) => [a] -> a sum' xs = foldl (+) 0 xs こう書き換えられる sum' :: (Num a) => [a] -> a sum' = foldl (+) 0 fold (+) 0 はリストを受け取る関数を返すため 他の例 fn x =…

すごいH本 part24

メリークリスマス チキン食いました 関数合成 .関数を使う。 他の関数に渡す関数をその場で作るときに使う。ラムダ式でできるが、関数合成のほうが簡潔に書けるらしい。 *Main> :t (.) (.) :: (b -> c) -> (a -> b) -> a -> c 関数を2つ引数にとって引数を1…

すごいH本 part23

$を使った関数適用 関数適用 = 関数呼び出しのこと 括弧の数を少なくしたい場合に役に立つらしい *Main> :t ($) ($) :: (a -> b) -> a -> b 普通の関数適用は左結合 f a b c は、 ((f a) b) c) となるので、(f a)から適用される。 $を使わない例 *Main> sum …

すごいH本 part22

真・畳み込みのコーナー 無限リストを畳み込む and 関数を foldr で実装し、foldr が無限リストを正しく処理できるのを確認していく 実装する and' :: [Bool] -> Bool and' xs = foldr (&&) True xs リストが全部Trueの場合にTrueを返して欲しいので、(&&)関…

すごいH本 part21

続・畳み込みのコーナー foldl1 と foldr1 foldl と foldr に似ているが、初期アキュムレータを明示的に与える必要がない 最大値を求める maximum を実装すゆ maximum' :: (Ord a) => [a] -> a maximum' = foldl1 max 実行結果 *Main> maximum' [1,2,3,4,5] …

すごいH本 part20

畳み込み リストに対する関数を扱う際、 基底部は空リストとし、パターンを使ってリストを先頭要 素と残りのリストに分解する というパターンが頻繁に出てくるので、Haskell には 畳み込み(fold) と呼ばれる便利な関数があるらしい。 畳み込みを使うと、デ…

すごいH本 part19

ラムダ式 ラムダ式とは、1回だけ必要な関数を作る時に使う無名関数です。 通常、高階関数に渡す関数を作るためだけに使われるらしい バックスラッシュを書いてからこのようにする。 (\{引数1} {引数2} -> {関数本体}) 普通、ラムダ式は括弧で囲むとのこと。 …

すごいH本 part18

map と filter ふたたび 10万以下の数のうち3829で割り切れる最大の数を探す largestDivisible :: Integer largestDivisible = head (filter p [100000,99999..]) where p x = x `mod` 3829 == 0 実行結果 *Main> largestDivisible 99554 10000 より小さい全…

すごいH本 part17

便利な関数 map 関数とリストを受け取ってその関数をリスト全ての要素に適用して新しいリストを生成する。 *Main> :t map map :: (a -> b) -> [a] -> [b] 実装 map' :: (a -> b) -> [a] -> [b] map' _ [] = [] map' f (x:xs) = f x : map' f xs 実行 *Main> …

すごいH本 part16

高階関数を実装する 高階関数は関数を引数として受け取ることができるし、返り値として関数を返すこともできる。 関数を受け取ってそれを2回適用する高階関数 applyTwice :: (a -> a) -> a -> a applyTwice f x = f (f x) 実行結果 *Main> applyTwice (+3) 1…

すごいH本 part15

高階関数 引数に関数を受け取ったり、関数を返すような関数を高階関数という。 Haskell を学ぶ上でとても大事な考え方らしい。 カリー化関数 カリー化関数とは複数の引数を取る代わりに、常にちょうど1つの引数を取る関数です。 カリー化関数が呼び出される…

すごいH本 part14

クイックソートを実装する ソートアルゴリズムはこんな感じ リストから任意の数を選ぶ(この数字をピボットと呼ぶ) ピボットより大きい数字を右側に、ピボット以下の数字を左側に移動する ピボットを除いた左右のリストに対して、1. 2. の手順を繰り返してい…