できたらいいなAndroidアプリ

Androidに限らずいろいろ書いていく。

プログラミングHaskell 第2章 はじめの一歩

リスト操作

takeとdropの第2引数は空リストでも良いらしい。

Prelude> take 3 []
[]
Prelude> drop 3 []
[]

なので、headとtake 1 とtailとdrop 1 は違う。

Prelude> head []
*** Exception: Prelude.head: empty list
Prelude> take 1 []
[]
Prelude> tail []
*** Exception: Prelude.tail: empty list
Prelude> drop 1 []
[]

他にどんな関数があるのかググってみたら、すんげ~たくさんあった。

https://downloads.haskell.org/~ghc/7.6-latest/docs/html/libraries/haskell98-2.0.0.2/List.html

だけど、知らない記号だらけで、中身はよくわからん。

xsの謎、解明

第1章で関数の定義に出てきた(x:xs)のxs。sって何だろう?と思っていたけど、複数形のsらしい。

Haskellでは慣習として、引数がリストである場合、名前の最後にsを付け、複数の値を表現できることを示す。たとえば、数値のリストはns、任意の値のリストはxs、そして文字のリストのリストはcssと名付けられるだろう。(2.4 Haskellプログラム 命名規則

練習問題の解答

1

2^3*4 = (2^3)*4
2*3+4*5 = (2*3)+(4*5)
2+3*4^5 = 2+(3*(4^5))

2

ghciで実行した

3

  • 関数名は小文字で始めなければならない。
  • 関数名を括るのはシングルクォートではなくバッククォート。
  • 同じレベルの定義は、行頭を揃えなければならない。

修正した定義

n = a `div` length xs
    where
      a = 10
      xs = [1,2,3,4,5]

実行結果

Main> n
2

4

lastを定義したら、怒られた。GHC.Listにlastが既にある?

<interactive>:65:1:
    Ambiguous occurrence ‘last’
    It could refer to either ‘Main.last’, defined at test.hs:9:1
                          or ‘Prelude.last’,
                             imported from ‘Prelude’ at test.hs:1:1
                             (and originally defined in ‘GHC.List’)

myLastで定義した。

myLast1 xs = xs !! ((length xs) - 1)
myLast2 [x] = x
myLast2 (x:xs) = myLast2 xs
myLast3 xs = head (drop ((length xs) - 1) xs)
myLast4 xs = (drop ((length xs) - 1) xs) !! 0
myLast5 xs = head (reverse xs)

5

またまた怒られたので、myInitで定義した。

myInit1 xs = reverse (tail (reverse xs))
myInit2 [x] = []
myInit2 (x:xs) = [x] ++ (myInit2 xs)
myInit3 xs = take ((length xs) - 1) xs

どうしても制御文が頭をよぎる。 (xs:x)って書けたら良いな。 whereを全然使ってなかった。