Haskell始めました

以前少しだけ触ったことがあってモナドで挫折していたHaskell。最近自分のスキルがあがっていない感を感じていて危機感を覚えたので、もう一度入門し直してみようと思って。学習の記録を残します。

小さいことからコツコツと書いていきます。

とりあえず簡単なリストについて

  • リストは[a,b,c]で作れる
[1,2,3,4,5]
["hello","haskell"]
  • 文字列の実態は文字のリスト
['h','e','l','l','o'] --"hello"
  • リストの中に入れられるのは同じ型のものだけ
[1,2,3,4,5] --OK
[1,'a',"hello"] --Error
  • Lispにおけるcar cdrは head tail
head [1,2,3,4,5] -- 1
tail [1,2,3,4,5] --[2,3,4,5]
  • Lispにおけるconsは 「:」
1 : [2,3,4,5] -- [1,2,3,4,5]

関数について

  • 書式
--test.hs
square n = n * n
  • 型を明示的に指定することもできる
--test.hs
square :: Int -> Int  -- squareという関数は、Intを引数にとり、Intを返す
square n = n * n  -- 関数定義の実体
  • 引数でパターンマッチもできる
--test.hs
times :: Int -> String -> [String]  -- repeat という関数は、Intを第一引数、Stringを第二引数にとり、Stringのリストを返す
times 0 str = []
times n str = str : times (n - 1) str
-- in REPL
> :l test.hs
> times 2 "hoge" --["hoge","hoge"]
  • 型変数で、「どんな型でもいいよ」を表すこともできる
times :: Int -> a -> [a]  -- times という関数は、Intを第一引数、何らかの型を第二引数にとり、そのリストを返す
times 0 x = []
times n x = x : times (n - 1) x
-- in REPL
> :l test.hs
> times 2 "hoge" --["hoge","hoge"]
> times 2 100 --[100,100]
> times 2 ["word","list"] --[["word","list"],["word","list"]]
  • バッククオートで囲むと 引数 `関数` 引数という書き方ができる
--in REPL
> :l test.hs
> 4 `times` "hey!" -- ["hey!","hey!","hey!","hey!"]
  • たとえば引き数をふたつとる関数を引き数ひとつで適応すると、カリー化された関数が返される
times :: Int -> a -> [a]
times 0 x = []
times n x = x : times (n - 1) x

twice = times 2
thrice = times 3
--in REPL
> :l test.hs
> twice "hey!" -- ["hey!","hey!"]
> thrice "hey!" -- ["hey!","hey!","hey!"]


とりあえず今日はここまで。このあたりまではとくにつまづくポイントもない。