Closed19

Programming in Haskell 2nd editionやる

ピン留めされたアイテム
shuntakashuntaka

用語リスト

名前 英語 説明
GHC Glasgow Haskell Compiler 名前の通り
GHCi Glasgow Haskell Compiler interactive 対話型インタプリンタ
プレリュード関数 組み込み関数が定義されているモジュール
全域関数 すべての入力対して出力の値が定義されているのが全域関数、入力によっては出力の値が未定義になる関数が部分関数

常用するコマンド(随時更新)

hsファイルの実行
runghc <ソースファイル>
環境の確認
ghci tui
REPL
ghci
# ソースファイルを読み込んで、REPL起動
ghci <ソースファイル>
shuntakashuntaka

著者前書き

Haskellは純粋関数型のプログラミング言語

Scalaとかは関数型のプログラミング言語なのかな。Haskellは「純粋」な点が違う(?)

  • I
    • 関数
    • リスト内包表記
    • 再帰関数
    • 高階関数
  • II
    • モナド
    • 構文解析
    • Foldable
    • 遅延評価
    • プログラムの論証
shuntakashuntaka

1.5.2.

where は局所定義のためのキーワード

qsort2 (x : xs) = qsort smaller ++ [x] ++ qsort larger
  where
    smaller = [a | a <- xs, a <= x]
    larger = [b | b <- xs, b > x]

以下の2つが局所的に定義されている

  • xsからx以下である全ての要素aを取り出して作ったリストsmaller
  • xsからxより大きい全ての要素bを取り出して作ったリストlarger
shuntakashuntaka

2.4.

Haskellでは、言語において最も中心的な役割を担う関数適用に対して空白文字を使い、乗算対しては*を明記します。

関数適用は他のすべての演算子よりも高い結合順位を持ちます。

こんな感じ?

f a b + c*d
(((f a) b) + (c*d))
shuntakashuntaka

2.5.1.

Haskellでは、慣習として、引数がリストである場合には名前の末尾にsを付けて複数の値を含んでいる可能性を示します。

  • 数値のリスト -> ns
  • 任意の値のリスト -> xs
  • 文字のリストのリスト -> css
shuntakashuntaka

関数の構造がまだ身についていない 😵‍💫

  • 型定義
    • 関数名 :: 戻り値
    • 関数名 :: 引数 -> 戻り値
  • 実際の定義
    • 関数名 引数 = 処理
shuntakashuntaka

3.1.

vが型Tの値であるという意味で「v :: T」という表記を使います。「v::T」は、「vの方はTである」と読みます。

ghci> False :: Bool
False
ghci> not False :: Bool
True

GHCiでは、:typeコマンドを式の前に付けると式の型が表示されます

ghci> :type not
not :: Bool -> Bool
ghci> :type False
False :: Bool
ghci> :type not False
not False :: Bool

さらっとプレリュード関数の定義調べるのに便利?hoogleとかあるっぽいけど。

ghci> :type head
head :: GHC.Stack.Types.HasCallStack => [a] -> a

shuntakashuntaka

3.2.

基本型

英名 和名 説明
Bool 真理値
Char 文字
String 文字列
Int 固定長整数 -2^63 ~ 2^63-1 の範囲を超えると予期せぬ結果が生じる
Integer 多倍長整数
Float 単精度浮動小数点数
Double 倍精度浮動小数点数

型クラスと型クラスのインスタンスという概念を理解しないと...(これはAIが生成したので正確性)

shuntakashuntaka

3.3.

リスト型

T型の要素を持つリストの型を[T]と書き込ます

ghci> [False,True,False] :: [Bool]
[False,True,False]
ghci> ['a', 'b', 'c', 'd'] :: [Char]
"abcd"
ghci> ["One", "Two", "Three"] :: [String]
["One","Two","Three"]
shuntakashuntaka

3.5.

型T1の引数を型T2の返り値に変換する関数の型を「T1 -> T2」と書きます

not :: Bool -> Bool
even :: Int -> Bool (整数か偶数かを判定するプレリュード関数)

Haskellの慣例に従って、関数定義の前で関数の型を(型注釈を使って)宣言

プログラマーにより指定された型の情報は、型推論を使って自動的に決定された型と照合されます。

関数は、全域関数である必要がないことに注意してください。つまり、引数として与えらえる値によっては、結果が定義されていなくてもかまいません。

headには空リストに対しては定義でされていない話がある。headの定義は、[a] -> aだからなぁ。
でもこれ保証できるプログラミング言語はなくないか?

shuntakashuntaka

3.6.

() 過剰にならない2つの仕組み。

  1. 型の中の->は右結合
    Int -> Int -> Int -> Int
    (Int -> (Int -> (Int -> Int)))

  2. 空白文字を用いて表す関数適用は、左結合
    mult x y z
    (((mult x) y) z)

shuntakashuntaka

3.7.

length :: [a] -> Int

任意の型aに対して、Intを返却する。1つ以上の型変数を含む型や、そのような型を持つ式は多相的と呼ばれる
[a] -> Int は多相型で、lengthは多相関数です。

zip :: [a] -> [b] -> [(a, b)]

どちらかというと3.6.の話だけど、zipを眺めていて、引数を複数設定したHaskellの関数はすべてカリー化で実現しているのかな。
タプルを渡せば引数みたいなものではあるけど。

multi :: Int -> Int -> Int -> Int
multi x y z = x * y * z

multi2 :: (Int, Int, Int) -> Int
multi2 (x, y, z) = x * y * z
shuntakashuntaka

型クラス

クラス名 JP 型クラスのインスタンスとか説明
Eq 同等クラス Bool, Char,String,Integer,Float,Doubleといった基本型
Ord 順序クラス 値が順序つけられる型の集合。前述のような基本型もすべてOrdクラスのインスタンス
Show 表示可能クラス これも基本型はすべてShowクラスのインスタンス
Read 読込可能クラス 文字列->値。値->文字列のShowと対
Num 数値クラス
Intergral 整数クラス

数値を書いて型推論でLinterがIntegerとどっちかわからん的なこと言われるのは、数値がIntとIntegerに所属しているから。という理解でいいのかしらね。

  • Eq
    • ==
    • /=
  • Ord
    • <
    • <=
    • >
    • >=
    • min
    • max
  • Show
    • show :: a -> String
  • Read
    • read :: String -> a
  • Num
    • +
    • -
    • *
    • negate 数値符号の反転
    • abs 絶対値の返却
    • signum 正
shuntakashuntaka

このガード付きの等式、ifがネストしなくていいな

signum3 :: Int -> Int
signum3 n
  | n < 0 = -1
  | n == 0 = 0
  | otherwise = 1
shuntakashuntaka

=>はコンテキストで、型クラス制約を貸すときに書くんだね
型インスタンスでint -> intと書いていたところを、x -> xとコンテキスト割り当てた引数を使うのが違いかなぁ

-- test1 :: Int -> Int
-- test1 a = a
-- 型引数あり
test1 :: (Integral x) => x -> x
test1 a = a
このスクラップは4ヶ月前にクローズされました