Prelude モジュールを読む (5) Data.Ordering, Data.Ord, Data.Bounded

Prelude モジュールを読む (5) Data.Ordering, Data.Ord, Data.Bounded

Prelude モジュールは purescript-prelude パッケージで定義されているモジュールです。

今回は以下の3つのモジュールを確認します。

  • Data.Ordering
  • Data.Ord
  • Data.Bounded

Data.Ordering

PureScript Haskell
Ordering Ordering

Ordering 型

data Ordering = LT | GT | EQ  

Data.Ord

PureScript Haskell
Ord 型クラス Ord 型クラス
compare compare
min min
max max
comparing Data.Ord.comparing
clamp
between
(>=) (>=)
(>) (>)
(<=) (<=)
(<) (<)

Ord 型クラス

Haskell では compare 以外にも結構たくさんメソッドがあるので、こっちの方がスッキリしていますね。

class Eq a <= Ord a where  
  compare :: a -> a -> Ordering  

min

min :: forall a. Ord a => a -> a -> a  
min x y =  
  case compare x y of  
    LT -> x  
    EQ -> x  
    GT -> y  

max

max :: forall a. Ord a => a -> a -> a  
max x y =  
  case compare x y of  
    LT -> y  
    EQ -> x  
    GT -> x  

comparing

Haskell の場合、Prelude には入っていないですね。

comparing :: forall a b. Ord b => (a -> b) -> (a -> a -> Ordering)  
comparing f x y = compare (f x) (f y)  

何かに変換してから比較したい場合はちょくちょくあるので、Preludeにあっても良いのかもしれません。

clamp

この関数は見たことないですね。

clamp :: forall a. Ord a => a -> a -> a -> a  
clamp low hi x = min hi (max low x)  

ドキュメントに使い方が載っています。

let f = clamp 0 10  
f (-5) == 0  
f 5    == 5  
f 15   == 10  

上限と下限を設定できる感じですね。

between

これもないですね。

between :: forall a. Ord a => a -> a -> a -> Boolean  
between low hi x  
  | x < low = false  
  | x > hi = false  
  | true = true  

名前通りの動作です。

let f = between 0 10  
f 0    == true  
f (-5) == false  
f 5    == true  
f 10   == true  
f 15   == false  

(>=)

greaterThanOrEq :: forall a. Ord a => a -> a -> Boolean  
greaterThanOrEq a1 a2 = case a1 `compare` a2 of  
  LT -> false  
  _ -> true  

infixl 4 greaterThanOrEq as >=  

(>)

greaterThan :: forall a. Ord a => a -> a -> Boolean  
greaterThan a1 a2 = case a1 `compare` a2 of  
  GT -> true  
  _ -> false  

infixl 4 greaterThan as >  

(<=)

lessThanOrEq :: forall a. Ord a => a -> a -> Boolean  
lessThanOrEq a1 a2 = case a1 `compare` a2 of  
  GT -> false  
  _ -> true  

infixl 4 lessThanOrEq as <=  

(<)

lessThan :: forall a. Ord a => a -> a -> Boolean  
lessThan a1 a2 = case a1 `compare` a2 of  
  LT -> true  
  _ -> false  

infixl 4 lessThan as <  

Data.Bounded

topbottomという名前良いですね。

PureScript Haskell
Bounded 型クラス Bounded 型クラス
top maxBound
bottom minBound

Bounded 型クラス, top, bottom

class Ord a <= Bounded a where  
  top :: a  
  bottom :: a  

instance boundedBoolean :: Bounded Boolean where  
  top = true  
  bottom = false  

instance boundedInt :: Bounded Int where  
  top = topInt  
  bottom = bottomInt  

foreign import topInt :: Int  
foreign import bottomInt :: Int  

-- | Characters fall within the Unicode range.  
instance boundedChar :: Bounded Char where  
  top = topChar  
  bottom = bottomChar  

foreign import topChar :: Char  
foreign import bottomChar :: Char  

instance boundedOrdering :: Bounded Ordering where  
  top = GT  
  bottom = LT  

instance boundedUnit :: Bounded Unit where  
  top = unit  
  bottom = unit  

foreign import topNumber :: Number  
foreign import bottomNumber :: Number  

instance boundedNumber :: Bounded Number where  
  top = topNumber  
  bottom = bottomNumber  

exports.topInt = 2147483647;  
exports.bottomInt = -2147483648;  

exports.topChar = String.fromCharCode(65535);  
exports.bottomChar = String.fromCharCode(0);  

exports.topNumber = Number.POSITIVE_INFINITY;  
exports.bottomNumber = Number.NEGATIVE_INFINITY;  

感想

Ord 型クラスがスッキリしていて良いですね。

これで半分ぐらい確認したのであと半分・・・。

進捗

  • Control.Applicative
  • Control.Apply
  • Control.Bind
  • Control.Category
  • Control.Monad
  • Control.Semigroupoid
  • Data.Boolean
  • Data.BooleanAlgebra
  • Data.Bounded
  • Data.CommutativeRing
  • Data.DivisionRing
  • Data.Eq
  • Data.EuclideanRing
  • Data.Field
  • Data.Function
  • Data.Functor
  • Data.HeytingAlgebra
  • Data.Monoid
  • Data.NaturalTransformation
  • Data.Ord
  • Data.Ordering
  • Data.Ring
  • Data.Semigroup
  • Data.Semiring
  • Data.Show
  • Data.Unit
  • Data.Void