Haskell 勉強メモ2
明示的な型宣言
Haskellの型宣言は2行で書く模様。こういう書き方は初めて。
removeNonUppercase :: [Char] -> [Char] removeNonUppercase st = [c | c <- st, c `elem` ['A' .. 'Z']] *Main> removeNonUppercase("HelloWorld") "HW" addThree :: Int -> Int -> Int -> Int addThree x y z = x + y + z *Main> addThree 1 2 3 6
Scalaだとこうかな。
def removeNonUppercase(st: Seq[Char]): Seq[Char] = { for (c <- st if ('A' to 'Z').contains(c)) yield c } removeNonUppercase("HelloWorld") // val res6: Seq[Char] = Vector(H, W) def addThree(x: Int)(y: Int)(z: Int): Int = x + y + z addThree(1)(2)(3) // val res7: Int = 6
一般的なHaskellの型
他の言語同様、Int
型がありマシンのワードサイズによって異なる模様。64ビットCPUの場合Intの範囲は -2^63〜2^63-1 なのでScalaだとLong型相当。他にInteger
型があって、これは有界ではなく大きな数値が扱える。BigInt
的なものか。
factorial :: Integer -> Integer factorial n = product [1 .. n] *Main> factorial 50 30414093201713378043612608166064768844377641568960512000000000000
def factorial(n: BigInt) = (BigInt(1) to n).foldLeft(BigInt(1)){ (a, b) => a * b} factorial(BigInt(50)) // val res8: BigInt = 30414093201713378043612608166064768844377641568960512000000000000
FloatとDouble。Floatは単精度浮動小数点数、Doubleは倍精度浮動小数点型。
円の面積を求める関数で試してみる。
circumference :: Float -> Float circumference r = 2 * pi * r *Main> circumference 4.0 25.132742 circumference' :: Double -> Double circumference' r = 2 * pi * r *Main> circumference' 4.0 25.132741228718345
def circumferenceF(r: Float): Float = 2.0f * math.Pi.toFloat * r def circumferenceD(r: Double): Double = 2.0 * math.Pi * r circumferenceF(4.0f) // val res9: Float = 25.132742 circumferenceD(4.0) // val res10: Double = 25.132741228718345
他にも
- 真偽値
Bool
(True, False
) Char
型(Unicode文字を表し、シングルクォート'
で括って表記する)- タブルも型。空のタプル
()
も型の一つで、ただ一つのあたい()
のみをもつ※これはユニットと呼ばれる。