第八章:數字相關的型別類

夢飛發表於2017-02-27

Haskell中基本的判斷大小、數值運算等都不是語法結構,而是通過函式實現的,本章介紹與之相關的型別類和常用的函式。

data和型別約束:永遠不要在你的資料型別宣告前加上型別類的約束。型別約束應該應該用來約束普通函式的引數型別,進而幫助編譯器確定函式的行為,而不是約束資料的行為。

1.順序類 Ord

class (Eq a) => Ord a where
    compare :: a -> a -> Ordering
    (<), (<=), (>=), (>) :: a -> a -> Bool
    max, min :: a -> a -> a

推導規則:按照建構函式書寫的順序,後面的建構函式建立的值大於前面的;相同的建構函式,則按照從前向後的位置順序比較引數的大小。

2.列舉類 Enum

那些可以被一一列舉的型別,比如Char,Bool。列舉類代表的是一個有序不重複的值的集合。

class Enum a where
    succ, pred :: a -> a
    --後/前一個元素
    toEnum :: Int -> a
    --列舉中對應次序的元素
    fromEnum :: a -> Int
    --元素在列舉中的次序
    --如果次序超過了Int能表示的範圍,結果就不確定了

    enumFrom :: a -> [a] -- [n..]
    enumFromThen :: a -> a -> [a] -- [n,n’..]
    enumFromTo :: a -> a -> [a] -- [n..m]
    enumFromThenTo :: a -> a -> a -> [a] -- [n,n’..m]
    -- Default declarations given in Prelude

推導規則:建構函式不需要引數的資料型別才可以使用Enum推導。

3.邊界類 Bounded

有上下邊界的資料型別

class Bounded a where
    minBound, maxBound :: a

推導規則:上邊界和下邊界是按照建構函式的書寫順序決定的。

4.數字類 Num

數字類是Haskell中所有數字型別的父類型別類

enter image description here

enter image description here

  • Numeric Literals

    fromInteger :: (Num a) => Integer -> a
    fromRational :: (Fractional a) => Rational -> a
    
  • Arithmetic and Number-Theoretic Operation

    class (Eq a, Show a) => Num a where
         (+), (-), (*) :: a -> a -> a
         negate :: a -> a
         abs, signum :: a -> a
         fromInteger :: Integer -> a
    
    
    class (Num a, Ord a) => Real a where
         toRational :: a -> Rational
         class (Real a, Enum a) => Integral a where
         quot, rem, div, mod :: a -> a -> a
         quotRem, divMod :: a -> a -> (a,a)
         toInteger :: a -> Integer
    
    
    class (Num a) => Fractional a where
         (/) :: a -> a -> a
         recip :: a -> a
         fromRational :: Rational -> a
    
    
    class (Fractional a) => Floating a where
         pi :: a
         exp, log, sqrt :: a -> a
         (**), logBase :: a -> a -> a
         sin, cos, tan :: a -> a
         asin, acos, atan :: a -> a
         sinh, cosh, tanh :: a -> a
         asinh, acosh, atanh :: a -> a
    
    
    class (Real a, Fractional a) => RealFrac a where
         properFraction :: (Integral b) => a -> (b,a)
         truncate, round :: (Integral b) => a -> b
         ceiling, floor :: (Integral b) => a -> b
    
    
    class (RealFrac a, Floating a) => RealFloat a where
         floatRadix :: a -> Integer
         floatDigits :: a -> Int
         floatRange :: a -> (Int,Int)
         decodeFloat :: a -> (Integer,Int)
         encodeFloat :: Integer -> Int -> a
         exponent :: a -> Int
         significand :: a -> a
         scaleFloat :: Int -> a -> a
         isNaN, isInfinite, isDenormalized, isNegativeZero, isIEEE
         :: a -> Bool
         atan2 :: a -> a -> a
    
    
    gcd, lcm :: (Integral a) => a -> a-> a
    (ˆ) :: (Num a, Integral b) => a -> b -> a
    (ˆˆ) :: (Fractional a, Integral b) => a -> b -> a
    fromIntegral :: (Integral a, Num b) => a -> b
    realToFrac :: (Real a, Fractional b) => a -> b
    
  • 整數的表示:Int 和 Integer,前者固定位元組表示,和c中長整型類似,後者處理大數,上下限與機器記憶體相關

  • 與Float相比,Double精度高但速度慢

  • 上一章的Fractional Floating 沒將Ord作為父類,但他們都是Real的例項,Ord是Real的父型別類。

  • quot rem div mod

  • 其他說明

相關文章