𝖄𝕺🌎𝕿𝕽𝕺¥

𝖄𝕺🌎𝕿𝕽𝕺¥

𝕴 𝖉𝖔 𝖒𝖆𝖌𝖎𝖈
github

Haskellノート2

タイプ#

特徴#

強力なタイプ

静的な

自動的に推論されることができる

基本タイプ#

Char
Bool
Int 一般的に使用される 固定幅の整数 通常32/64ビット幅
Integer あまり使用されない 可変長
Double 一般的に使用される 浮動小数点数
Float あまり使用されない 計算が遅い
Prelude> :type 'a'
'a' :: Char

Prelude> 'a'            -- 自動的に推論される
'a'

::記号
Prelude> 'a' :: Char    -- 明示的な署名
'a'

関数の呼び出し#

Prelude> odd 3
True

Prelude> compare 2 3
LT
例:LT EQ GT

Prelude> (compare 2 3) == LT
True

Prelude> compare (sqrt 3) (sqrt 6)  -- ここで括弧を取り除くことはできません
LT

複合データ型:リストとタプル#

違い?#

リストは任意の長さであり、同じタイプの値のみを含むことができます。

タプルの長さは固定されていますが、異なるタイプの値を含むことができます。

再帰可能性#

[[Int]] は [Int] タイプの値を含むリストであり、 [Int] は Int タイプの値を含むリストであり、a の型変数を Int タイプで置き換えます。

リスト [] と head、tail、last;take、drop#

head は最初の要素を取得し、tail は最初以外のすべてを取得します。
last は最後の要素を取得します。

Prelude> head [1, 2, 3, 4]
1

Prelude> head []
*** Exception: Prelude.head: empty list

Prelude> tail "list"
"ist"
ghci> last [1,2,3]
3
Prelude> take 2 [1, 2, 3, 4, 5]
[1,2]
Prelude> drop 2 [1, 2, 3, 4, 5]
[3,4,5]
Prelude> drop 4 [1, 2]
[]
Prelude> drop (-1) "foo"    --最初の引数が0以下の場合、drop関数は入力リスト全体を返します
"foo"

タプル () と fst、snd#

サイズは少なくとも 2 です

タプルの型は、含まれる要素の数、位置、および型によって決まります

Prelude> :type (True, "hello")
(True, "hello") :: (Bool, [Char])
Prelude> (4, ['a', 'm'], (16, True))
(4,"am",(16,True))
Prelude> :t ()
() :: ()
Prelude> fst (1, 'a')
1

Prelude> snd (1, 'a')
'a'

タプルの使用例#

  • 関数が複数の値を返す必要がある場合、これらの値をタプルにまとめて、関数の値としてタプルを返すことができます。

  • 固定長のコンテナを使用する必要がありますが、カスタムタイプを使用する必要がない場合、値をタプルでラップすることができます。

式を関数に渡すために括弧を使用する#

a b c d は (((a b) c) d) と等しい

純粋性#

副作用のある関数は 不純(impure)関数 と呼ばれ、副作用のない関数は 純(pure)関数 と呼ばれます。

副作用とは、関数内のグローバル変数の変更可能性、つまり、ある時点の値に依存することです。本質的には、関数の見えない(invisible)入力または出力です。Haskell の関数はデフォルトで副作用がありません:関数の結果は、明示的に渡されたパラメータにのみ依存します。

不純な関数の型シグネチャはすべて IO で始まります。以下は検出例です:

Prelude> :type readFile
readFile :: FilePath -> IO String
-- 不純な関数の型シグネチャはすべて IO で始まります

.hs ファイルのロード#

ghci で :load を使用します

変数#

変数が式にバインドされると、その変数の値は変更されません。.hs ファイルではできませんが、ghci コマンドラインでは可能です。

例:[Assign.hs]

条件付き評価#

異なるブランチ間の型は同じでなければなりません。
例:

[myDrop.hs]

-- file: ch02/myDrop.hs

myDrop :: Int -> [a] -> [a]
myDrop n xs = if n <= 0 || null xs    -- ## nullの使用法
              then xs   -- インデントは省略できません
              else myDrop (n - 1) (tail xs) -- インデントは省略できません

-- 代入(substitution)と書き換え(rewriting)
-- 変数nとxsを代入しました
-- myDrop関数を書き換えました

-- ## 遅延評価
-- 1行にまとめることもできます 例:[myDropX.hs](ch02/myDrop.hs)

-- ## 条件付き評価
-- null xsはxs == nullではありません
-- thenとelseの後の式は「ブランチ」と呼ばれます。
-- 異なるブランチ間の型は同じでなければなりません。
-- ifはブランチではありません。


-- 例:
-- Prelude> if True then 1 else "foo"

-- <interactive>:2:14:
--     No instance for (Num [Char])
--         arising from the literal `1'
--     Possible fix: add an instance declaration for (Num [Char])
--     In the expression: 1
--     In the expression: if True then 1 else "foo"
--     In an equation for `it': it = if True then 1 else "foo"

->
1 行に簡略化できます [myDropX.hs]

-- file: ch02/myDropX.hs
myDropX n xs = if n <= 0 || null xs then xs else myDropX (n - 1) (tail xs)

遅延評価#

例:[isOdd.hs]

-- file: ch02/isOdd.hs
isOdd n = mod n 2 == 1

-- ghci> isOdd (1+2)
-- True

--一般的には:XXXXXX
-- 最初:(1+2)
-- 2番目:mod 3 2
-- 3番目:1 == 1
-- True

--しかし、Haskellでは:
--(1+2)は最後に計算されます!実際に必要なときにisOdd (1 + 2)の値を計算します
--未評価の式の追跡レコードは「チャンク」と呼ばれます

再帰#

遅延評価に注意し、再帰 -> 再帰の終了 -> 再帰の戻り値
解説
例:[myDrop.hs]

多相性#

パラメータ多相性#

Prelude> :type last
last :: [a] -> a
ghci> last [1,2,3]
3

last に [Char] タイプのリストを渡すと、コンパイラはすべての a を Char で置き換え、[Char] -> Char のタイプを持つ last 関数を得ます。同様に、Int などの任意のタイプでも可能です。このようなタイプの多相性はパラメータ多相性と呼ばれます。

パラメータ多相性は、入力パラメータの実際のタイプを知る方法はありません。

不足#

Haskell にはサブクラス多相性や強制多相性(coercion polymorphism)はありません。

多パラメータ関数のタイプ#

例:

Prelude> :type take
take :: Int -> [a] -> [a]
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。