Unyablog.

のにれんのブログ

Haskell入門12日目

十二日目

isuconに出るのでSQLを学ばなきゃいけない。

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

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

7.7

  • 書かれてるイラストめっちゃ安倍さんっぽい顔してる
  • 再帰的な型の定義
    • リストとかそんなかんじそう
  • Cons とは...と思ったけど自分で定義したものか
    • (:)a -> [a] -> [a]
    • Consa -> NonyList a -> NonyList a
  • 記号文字だけをつかって関数に名前をつけると自動的に中置になる
  • 結合性宣言 infix*

  • ++ を実装してみよう

はじめに書いたのは

infixr ^++
(^++) :: NonyList a -> NonyList a -> NonyList a
x ^++ y = nfirst x ^++ nlast x y
        where nlast Empty y = y
              nlast (x:-:Empty) y = x:-: y
              nlast (x:-:xs) y = nlast xs y
              nfirst (Empty) = Empty
              nfirst (x:-:xs) = x :-: nfirst xs

そもそもパターンマッチできるかとおもったらできたのはよかったんだけど処理が終わらなくて悲しかった。

そこで手を加えて

infixr ^++
(^++) :: NonyList a -> NonyList a -> NonyList a
Empty ^++ y = y
x ^++ y = nfirst x ^++ nlast x y
        where nlast Empty y = y
              nlast (x:-:Empty) y = x:-: y
              nlast (x:-:xs) y = nlast xs y
              nfirst (Empty) = Empty
              nfirst (x:-:Empty) = Empty
              nfirst (x:-:xs) = x :-: nfirst xs

とすればまあ動きはしたけどもうちょっと良い書き方がありそう。

そこからひらめいて

infixr ^++
(^++) :: NonyList a -> NonyList a -> NonyList a
Empty ^++ y = y
(x:-:xs) ^++ y = x :-: xs ^++ y

とすればシュッと実装できてめでたかった。答え?もそんなかんじだった

パターンマッチ、便利。考えてみればこういう感じで使えるのは中置なので当然っぽかった。

  • 二分探索木、あんまよくわかってないけど実装したらついでに理解できてお得そう
  • とりあえず定義だけ見て書いてみたら全く同じだったので最高。ただこれだと
first.hs:182:1: Warning:
    Pattern match(es) are non-exhaustive
    In an equation for `treeInsert':
        Patterns not matched: _ (Node _ _ _)

というエラーが出てきて、なんだろうと思ったら otherwise を書いてないのが悪いらしい。ガードで otherwise 書かなかったら確かにコンパイラはどうすればいいんだって怒りそう。

foldr treeInsert EmptyTree [1,2,3,4]

foldl (flip(treeInsert)) EmptyTree [1,2,3,4]

は値が違うんだなあ(しみじみ)

でも後者と

foldl' (flip(treeInsert)) EmptyTree [1,2,3,4]

とは同じだった(そりゃそうだ。)

感想

  • foldl 明らかによくなさそう。
  • 標準ライブラリ関数の実装を学んでいく感じとても馴染みやすくてよい。自分が思ったこと次の節とかで解決されてることが多くて納得できる