Subscribed unsubscribe Subscribe Subscribe

Unyablog.

のにれんのブログ

Haskell入門6日目

六日目

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

京都行くまでにマスターするつもりだったけど半分いくのもムズそう。まあ急ぐよりじっくりやるほうがいいからこれでいいんだけど。

第5章

高階関数、聞いたことないですね。

そもそも関数返すってどういうことだ?メタっぽい気分。

5.1

  • カリー化は聞いたことある。スパイシー(百万遍にあるカレー屋)に行く時に友人がカリー化カリー化言ってた記憶。
  • 複数引数をとる関数は全てカリー化されている
  • max 4 5 の場合 (max 4) 5 の場合と等価
    • 前から順番に見ているっていうの、第一章あたりで不思議だったことだ。
  • :t max 4 のとき (Num a, Ord a) => a -> a
    • 一つ目が Num だったので Num に型クラス制約されたんですね。
    • 一つ目の引数を受け取ったあとに生成される関数ってstatic埋め込みみたいなやつなんだろうか。
  • 引数を一つだけのものも関数なので、そうしてできた関数に他の引数を入れてもちゃんと値が出る。
    • 確かに関数が変数になってる
  • let tempCompare = compare 8 in tempCompare 1 => GT

  • セクションは中置関数をカリー化するのに使う?

    • 割りと分かりにくい文法感はある
      • というか普通にそこに引数つければ普通の関数になるし
    • 引数を省略できるのがよいということかな?
    • (\10) 200 => 20.0 になるのはおもしろいと思った
  • ghci は show がないからエラーが出るだけ。

5.2

  • 引数に関数入れるのやばい。
    • なるほどここでセクションが使えるんですね〜
  • applyTwice reverse [1,2,3] => [1,2,3]
  • zipWith はシュッとかけた。書いたら載ってるやつと全く同じものになった。
  • flip
    • 適当に書いたら合ってた。

5.3

  • map すき。でもmapかけるとき大体リスト内包でできるからリスト内包で済ますことが多い。
    • 見た感じmapの方が記述が短くなりそう。
  • filter
    • これしか書き方ないかなあというかんじで書いたらお手本と一緒だった。
    • Haskell 三項演算子っぽいのはないのかな?(python っぽい
nonyFilter f (x:xs) = (if f x then x) : nonyFilter f xs

的なの書いてみたけどエラーだった。よく見たら普通に上の文 else が欠けてるじゃん。

ということでelse では空を返せばよいのか!!!とやってみたけど、haskellって null みたいなのは返せないんですねえ。

undefined というのがあるみたいだけどエラー吐いて終わったし。

結局

nonyFilter f (x:xs) = if (f x) then [x] else [] ++ nonyFilter f xs

とすればスッキリできました。

追記: これだと (else [] ++ nonyFilter f xs) となってしまうので、

nonyFilter f (x:xs) = (if (f x) then [x] else []) ++ nonyFilter f xs

とする必要がありました。

  • ghci、:q で終了できるの初めて知って涙を流している。
  • 遅延評価いいですね。これ同じように書いて java でやったらどうなるんだろう。リスト一回全部作りそう。
  • takeWhile とか便利関数だ。

適当に

sum [x | x <- [1..], x^2 < 10000]]

って書いてみたら止まらなくなってしまったけど確かに延々と評価し続けそう。

リスト内包でぺぺっとかけると思ったけど案外長くなるなあ。

  • コラッツ列
    • そもそもdiv がわからずに truncate で無理やり頑張ってたらワケわからなくなってやめた。
    • めちゃくちゃ時間かかってなんとか実装できた。いろいろ混乱してた。
colattz :: Integer -> [Integer]
colattz x
    | x == 1 = [1]
    | even x = x : colattz (div x 2)
    | otherwise = x : colattz (x * 3 + 1)

として length (filter (>14) (map length (map colattz [1..100]))) => 71

となった。これであってる…んじゃないかな。

感想

いろいろやったことないことできて面白かった。python とか java8 だとこういうことできるのかな。(確かjava7以前だと無名クラスというので無理やり頑張ってたらしいような