Haskell-types-and-type-class

提供:Dev Guides
移動先:案内検索

Haskell-型と型クラス

Haskellは関数型言語であり、厳密に型指定されています。つまり、アプリケーション全体で使用されるデータ型は、コンパイル時にコンパイラーに認識されます。

組み込み型クラス

Haskellでは、すべてのステートメントは数式と見なされ、この式のカテゴリは Type と呼ばれます。 「タイプ」は、コンパイル時に使用される式のデータ型であると言えます。

*Type* の詳細については、「:t」コマンドを使用します。 一般的な方法では、 *Type* は値と見なすことができますが、 *Type Class* は一連の類似した種類の種類と見なすことができます。 この章では、さまざまな組み込み型について学習します。

Int

*Int* は、整数型データを表す型クラスです。 2147483647〜-2147483647の範囲内のすべての整数は、 *Int* 型クラスに属します。 次の例では、関数* fType()*は定義されたタイプに従って動作します。
fType :: Int -> Int -> Int
fType x y = x*x + y*y
main = print (fType 2 4)

ここでは、関数* fType()のタイプを *int として設定しています。 この関数は2つの int 値を取り、1つの int 値を返します。 このコードをコンパイルして実行すると、次の出力が生成されます-

sh-4.3$ ghc -O2 --make *.hs -o main -threaded -rtsopts
sh-4.3$ main
20

整数

整数*は *Int のスーパーセットと見なすことができます。 この値は任意の数に制限されていないため、整数の長さには制限がありません。 Int 型と Integer 型の基本的な違いを確認するには、次のように上記のコードを変更しましょう-

fType :: Int -> Int -> Int
fType x y = x*x + y*y
main = print (fType 212124454 44545454454554545445454544545)

上記のコードをコンパイルすると、次のエラーメッセージがスローされます-

main.hs:3:31: Warning:
   Literal 44545454454554545445454544545 is out of the Int range -
   9223372036854775808..9223372036854775807
Linking main ...

このエラーは、関数fType()が1つのInt型値を予期しており、実際の大きなInt型値を渡すために発生しました。 このエラーを回避するには、タイプ「Int」を「Integer」で変更し、違いを観察しましょう。

fType :: Integer -> Integer -> Integer
fType x y = x*x + y*y
main = print (fType 212124454 4454545445455454545445445454544545)

今、それは次の出力を生成します-

sh-4.3$ main
1984297512562793395882644631364297686099210302577374055141

浮く

次のコードをご覧ください。 HaskellでのFloat型の動作を示しています-

fType :: Float -> Float -> Float
fType x y = x*x + y*y
main = print (fType 2.5 3.8)

この関数は、入力として2つの浮動小数点値を取り、出力として別の浮動小数点値を生成します。 このコードをコンパイルして実行すると、次の出力が生成されます-

sh-4.3$ main
20.689999

ダブル

*Double* は、末尾に倍精度の浮動小数点数です。 次の例を見てください-
fType :: Double -> Double -> Double
fType x y = x*x + y*y
main = print (fType 2.56 3.81)

上記のコードを実行すると、次の出力が生成されます-

sh-4.3$ main
21.0697

Bool

*Bool* はブール型です。 TrueまたはFalseのいずれかです。 HaskellでBool型がどのように機能するかを理解するには、次のコードを実行します-
main = do
   let x = True

   if x == False
      then putStrLn "X matches with Bool Type"
   else putStrLn "X is not a Bool Type"

ここでは、変数 "x"をBoolとして定義し、別のブール値と比較してその独自性を確認しています。 それは次の出力を生成します-

sh-4.3$ main
X is not a Bool Type

Char

Charはキャラクターを表します。 一重引用符内のすべては、キャラクターと見なされます。 次のコードでは、Char値を受け入れ、出力としてChar値を返すように、以前の* fType()*関数を変更しました。

fType :: Char-> Char
fType x = 'K'
main = do
   let x = 'v'
   print (fType x)

上記のコードは、 char 値 'v’で* fType()*関数を呼び出しますが、別のchar値、つまり 'K’を返します。 ここにその出力があります-

sh-4.3$ main
'K'

Haskellは型が宣言される前にその型をキャッチするのに十分なインテリジェントであるため、これらの型を明示的に使用しないことに注意してください。 このチュートリアルの以降の章では、異なる型とTypeクラスがHaskellを強く型付けされた言語にする方法を説明します。

EQタイプクラス

*EQ* 型クラスは、式の等価性をテストする機能を提供するインターフェイスです。 式の等価性をチェックするTypeクラスは、このEQ Type Classの一部である必要があります。

上記のすべての標準Typeクラスは、この EQ クラスの一部です。 上記の型のいずれかを使用して同等性をチェックするときはいつでも、実際には EQ 型クラスを呼び出しています。

次の例では、内部で「==」または「/=」操作を使用して EQ タイプを使用しています。

main = do
   if 8/= 8
      then putStrLn "The values are Equal"
   else putStrLn "The values are not Equal"

次の出力が得られます-

sh-4.3$ main
The values are not Equal

順序型クラス

*Ord* は、順序付けの機能を提供する別のインターフェイスクラスです。 これまで使用してきた *types* はすべて、この *Ord* インターフェイスの一部です。 EQインターフェースと同様に、Ordインターフェースは「>」、「<」、「<=」、「> =」、「compare」を使用して呼び出すことができます。

このタイプクラスの「比較」機能を使用した例を以下に示します。

main = print (4 <= 2)

ここで、Haskellコンパイラは4が2以下かどうかをチェックします。 そうではないので、コードは次の出力を生成します-

sh-4.3$ main
False

Show

*Show* には、引数を文字列として出力する機能があります。 引数が何であれ、結果を常に文字列として出力します。 次の例では、このインターフェイスを使用してリスト全体を印刷します。 「show」を使用してこのインターフェイスを呼び出すことができます。
main = print (show [1..10])

コンソールに次の出力が生成されます。 ここで、二重引用符は、文字列型の値であることを示しています。

sh-4.3$ main
"[1,2,3,4,5,6,7,8,9,10]"

Read

*Read* インターフェースはShowと同じことをしますが、結果を文字列形式で出力しません。 次のコードでは、 *read* インターフェイスを使用して文字列値を読み取り、それをInt値に変換しています。
main = print (readInt "12")
readInt :: String -> Int
readInt = read

ここでは、ストリング変数( "12")を readInt メソッドに渡し、変換後に12(Int値)を返します。 ここにその出力があります-

sh-4.3$ main
12

Enum

*Enum* は、Haskellのシーケンシャルまたは順序付けられた機能を有効にする別のタイプのクラスです。 このTypeクラスには、 *Succ、Pred、Bool、Char* などのコマンドでアクセスできます。

次のコードは、12の後続値を見つける方法を示しています。

main = print (succ 12)

それは次の出力を生成します-

sh-4.3$ main
13

跳ねる

上限と下限を持つすべてのタイプは、このタイプクラスに属します。 たとえば、 Int タイプのデータには、「9223372036854775807」の上限と「-9223372036854775808」の下限があります。

次のコードは、HaskellがInt型の最大および最小境界を決定する方法を示しています。

main = do
   print (maxBound :: Int)
   print (minBound :: Int)

それは次の出力を生成します-

sh-4.3$ main
9223372036854775807
-9223372036854775808

次に、Char、Float、およびBool型の最大および最小境界を見つけてみてください。

Num

この型クラスは数値演算に使用されます。 Int、Integer、Float、Doubleなどの型は、このTypeクラスの下にあります。 次のコードを見てください-

main = do
   print(2 :: Int)
   print(2 :: Float)

それは次の出力を生成します-

sh-4.3$ main
2
2.0

積分

*Integral* は、Num Type Classのサブクラスと見なすことができます。 Num Typeクラスはすべてのタイプの数値を保持しますが、Integralタイプクラスは整数のみに使用されます。 IntおよびIntegerは、このTypeクラスの下のタイプです。

フローティング

Integralと同様に、FloatingもNum Typeクラスの一部ですが、浮動小数点数のみを保持します。 したがって、 FloatDouble はこの型クラスの下にあります。

カスタムタイプクラス

他のプログラミング言語と同様に、Haskellでは開発者がユーザー定義型を定義できます。 次の例では、ユーザー定義型を作成して使用します。

data Area = Circle Float Float Float
surface :: Area -> Float
surface (Circle _ _ r) = pi * r ^ 2
main = print (surface $ Circle 10 20 10 )

ここでは、 Area という新しいタイプを作成しました。 次に、このタイプを使用して円の面積を計算しています。 上記の例では、「surface」は入力として Area を取り、出力として Float を生成する関数です。

ここで「データ」はキーワードであり、Haskellのすべてのユーザー定義型は常に大文字で始まることに注意してください。

それは次の出力を生成します-

sh-4.3$ main
314.15927