2017AdventCalendar
サンタさん、5000兆円ください ポイントフリースタイル この関数を sum' :: (Num a) => [a] -> a sum' xs = foldl (+) 0 xs こう書き換えられる sum' :: (Num a) => [a] -> a sum' = foldl (+) 0 fold (+) 0 はリストを受け取る関数を返すため 他の例 fn x =…
メリークリスマス チキン食いました 関数合成 .関数を使う。 他の関数に渡す関数をその場で作るときに使う。ラムダ式でできるが、関数合成のほうが簡潔に書けるらしい。 *Main> :t (.) (.) :: (b -> c) -> (a -> b) -> a -> c 関数を2つ引数にとって引数を1…
メリークリスマス みなさん、チキン食ってますか?サンタにはちゃんと5000兆円ほしいってお願いしましたか? ...よいでしょう。 この記事は、 しがないラジオ Advent Calendar 2017 - Adventar の24日目の投稿となります。 わたしは誰 軽く自己紹介をします…
$を使った関数適用 関数適用 = 関数呼び出しのこと 括弧の数を少なくしたい場合に役に立つらしい *Main> :t ($) ($) :: (a -> b) -> a -> b 普通の関数適用は左結合 f a b c は、 ((f a) b) c) となるので、(f a)から適用される。 $を使わない例 *Main> sum …
真・畳み込みのコーナー 無限リストを畳み込む and 関数を foldr で実装し、foldr が無限リストを正しく処理できるのを確認していく 実装する and' :: [Bool] -> Bool and' xs = foldr (&&) True xs リストが全部Trueの場合にTrueを返して欲しいので、(&&)関…
続・畳み込みのコーナー foldl1 と foldr1 foldl と foldr に似ているが、初期アキュムレータを明示的に与える必要がない 最大値を求める maximum を実装すゆ maximum' :: (Ord a) => [a] -> a maximum' = foldl1 max 実行結果 *Main> maximum' [1,2,3,4,5] …
畳み込み リストに対する関数を扱う際、 基底部は空リストとし、パターンを使ってリストを先頭要 素と残りのリストに分解する というパターンが頻繁に出てくるので、Haskell には 畳み込み(fold) と呼ばれる便利な関数があるらしい。 畳み込みを使うと、デ…
ラムダ式 ラムダ式とは、1回だけ必要な関数を作る時に使う無名関数です。 通常、高階関数に渡す関数を作るためだけに使われるらしい バックスラッシュを書いてからこのようにする。 (\{引数1} {引数2} -> {関数本体}) 普通、ラムダ式は括弧で囲むとのこと。 …
map と filter ふたたび 10万以下の数のうち3829で割り切れる最大の数を探す largestDivisible :: Integer largestDivisible = head (filter p [100000,99999..]) where p x = x `mod` 3829 == 0 実行結果 *Main> largestDivisible 99554 10000 より小さい全…
便利な関数 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> …
高階関数を実装する 高階関数は関数を引数として受け取ることができるし、返り値として関数を返すこともできる。 関数を受け取ってそれを2回適用する高階関数 applyTwice :: (a -> a) -> a -> a applyTwice f x = f (f x) 実行結果 *Main> applyTwice (+3) 1…
高階関数 引数に関数を受け取ったり、関数を返すような関数を高階関数という。 Haskell を学ぶ上でとても大事な考え方らしい。 カリー化関数 カリー化関数とは複数の引数を取る代わりに、常にちょうど1つの引数を取る関数です。 カリー化関数が呼び出される…
クイックソートを実装する ソートアルゴリズムはこんな感じ リストから任意の数を選ぶ(この数字をピボットと呼ぶ) ピボットより大きい数字を右側に、ピボット以下の数字を左側に移動する ピボットを除いた左右のリストに対して、1. 2. の手順を繰り返してい…
再帰 再帰とは、関数の定義の中で自分自身を呼び出す、という関数の定義の仕方 関数を再帰的に定義するためには、 問題を同じ種類のより小さな問題に分解する 問題の基底部を見つける 基底部とはこれ以上分解できない問題の単位 複数あることもある を行う必…
case 式 コード中のどこででもパターンマッチが使えるようになる。case は式である。 head' :: [a] -> a head' xs = case xs of [] -> error "error." (x:_) -> x 関数のパターンマッチは case のシンタックスシュガーとなっている。 head' :: [a] -> a head…
let 式 どこでも変数を束縛できる let 式が作る束縛は局所的でガード間で共有されない パターンマッチが使える 例 cylinder :: Double -> Double -> Double cylinder r h = let sideArea = 2 * pi * r * h topArea = pi * r ^ 2 in sideArea + 2 * topArea l…
パート10までやってきた自分えらい ガード 引数の構造で場合分け パターンマッチを使う 引数の値が満たす性質で場合分け ガードを使う 例 bmiTell :: Double -> String bmiTell bmi | bmi <= 18.5 = "You're underweight, you emo, you!" | bmi <= 25.0 = "Y…
やっていきのこころ パターンマッチ パターンに従ってデータを分解するときに使う luckey :: Int -> String luckey 7 = "Luckey!!!" luckey x = "Unluckey!!!" パターンが上から下の順で評価される パターンが合致するとそのパターンの本体が実行される *Mai…
やっていきの精神 型変数 *Main Lib> :t head head :: [a] -> a aが型変数 aはどんな型もとり得る 型変数を用いた関数は多相的関数と呼ばれる 型変数はa,bなど1文字で表現されることが多い 型クラス 何らかの振る舞いを定義するインターフェース 型は型クラ…
やっていき 型 コンパイル時に全ての型がわかっている 型推論がある 型を調べる 式の型が:t でわかる。::以降が型となる。 *Main Lib> :t 'a' 'a' :: Char *Main Lib> :t 3 3 :: Num t => t *Main Lib> :t "Hello" "Hello" :: [Char] *Main> :t boomBangs bo…
今日もやっていき タプル 違う型の要素を格納して1つの値にする サイズが固定 *Main> (1,3) (1,3) *Main> (3, 'a', "hoooo!!!") (3,'a',"hoooo!!!") サイズ2のタプルをペアという サイズ3のタプルをトリプルという 長さが同じでも違う型を含むタプルを違うも…
引き続き リスト内包表記 集合の内包的記法の概念に近いもの、らしい 集合論 - Wikibooks よくわからんので見てゆくことにする これがリストの内包表記らしい *Main Lib> [x*2 | x <- [1..10]] [2,4,6,8,10,12,14,16,18,20] リスト[1..10]から要素を取り出す…
引き続きすごいH本やっていく レンジ 数字 アルファベット などを列挙できる要素をリストにする *Main Lib> [1..20] [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] *Main Lib> ['a'..'z'] "abcdefghijklmnopqrstuvwxyz" *Main Lib> ['I'..'Q'] "IJK…
前回に引き続きやっていく blog.tokoyax.com Haskell のリスト 同じ型の要素を複数個格納できる *Main Lib> let lostNumbers = [4,8,15,16,23,42] *Main Lib> lostNumbers [4,8,15,16,23,42] リストの連結 *Main Lib> [1,2,3,4] ++ [5,6,7,8] [1,2,3,4,5,6,7…
前の記事でも少しふれたが、Haskell における関数についての続き blog.tokoyax.com 関数を組み合わせる doubleUs x y = x * 2 + y * 2 ↓ doubleUs x y = doubleMe x + doubleMe y このように関数を組み合わせて表現してゆく。 これは関数型でなくてもやって…
すごいH本中心に書いてゆく こちらにまとめることにした adventar.org
Elixir を触っていると関数型プログラミングに興味が湧いてきたので、すごいH本を読んでいこうと思う。 この本を読むことで関数型プログラミングの基本的な考え方を得たい。 そんでもって、めちゃくちゃエロいらしい。 今日は1日目。 イントロダクション Has…