簡體   English   中英

為什么Haskell中沒有間隔類型類?

[英]Why isn't there an interval typeclass in haskell?

也許我沒看對地方,但是在Haskell中找不到間隔的類型類。 在我看來,這種抽象將在許多情況下有用,因為在許多領域都使用了間隔。

這也可以從實現某種間隔結構( 間隔軟件包列表 )的黑客程序的不同軟件包的數量中看出。

使用類型類來實現不同類型的間隔(打開,關閉,...)會引起混淆,還是有其他概念可以幫助我構建自己的間隔(除了自己的數據類型之外)?

您可以使用-XFunctionalDependences-XFlexibleInstances來執行此-XFlexibleInstances (使用此方法編寫任何實例...)。 我在下面編寫了一些代碼,並帶有注釋以說明:

{-# LANGUAGE FlexibleInstances      #-}
{-# LANGUAGE FunctionalDependencies #-}

-- | Intervals with endpoints of type e.
class (Ord e) => Interval i e | i -> e where
  {-# MINIMAL inf, sup #-}
  -- lower bound ("infinimum") 
  inf :: i -> e
  -- upper bound ("supremum")
  sup :: i -> e

-- Is (X : Interval e) a valid Interval?
valid :: Interval i e => i -> Bool
valid x = sup x > inf x

-- Is (X : Interval e) an invalid Interval?
notValid :: Interval i e => i -> Bool
notValid = not . valid

-- Is (x : e) contained within (X : Interval e)
containsPoint :: Interval i e => i -> e -> Bool
x `containsPoint` p = p >= inf x && p <= sup x

-- Is (x : e) below (X : Interval e)
abovePoint :: Interval i e => i -> e -> Bool
x `abovePoint` p = p < inf x

-- Is (x : e) above (X : Interval e)
belowPoint :: Interval i e => i -> e -> Bool
x `belowPoint` p = p > sup x

-- For all (x : e) in (X : Interval e), (y : e) in (Y : Interval e),
-- x < y iff sup X < inf Y 
before :: Interval i e => i -> i -> Bool
x `before` y = sup x < inf y

-- For all (x : e) in (X : Interval e), (y : e) in (Y : Interval e),
-- x > y iff inf X > sup Y 
after :: Interval i e => i -> i -> Bool
x `after` y = inf x > sup y

-- For all (x : e) in (X : Interval e), (y : e) in (Y : Interval e),
-- x == y iff (inf X == inf Y) && (sup X == sup Y)
equals :: Interval i e => i -> i -> Bool
x `equals` y = inf x == inf y && sup x == sup y

-- For all (x : e) in (X : Interval e), (y : e) in (Y : Interval e),
-- x /= y iff (sup x < inf y) || (inf x > sup y)
nequals :: Interval i e => i -> i -> Bool
x `nequals` y = sup x < inf y || inf x > sup y

-- For all (x : e) in (X : Interval e), (y : e) in (Y : Interval e),
-- x <= y iff sup x <= inf y
eqBefore :: Interval i e => i -> i -> Bool
x `eqBefore` y = sup x <= inf y

-- For all (x : e) in (X : Interval e), (y : e) in (Y : Interval e),
-- x >= y iff inf x >= sup y
eqAfter :: Interval i e => i -> i -> Bool
x `eqAfter` y = inf x >= sup y

-- Does (X : Interval e) contain (Y : Interval e)?
contains :: Interval i e => i -> i -> Bool
x `contains` y = inf x <= inf y && sup y <= sup x

-- Is (X : Interval e) a subset of (Y : Interval e)?
isSubSetOf :: Interval i e => i -> i -> Bool
isSubSetOf = flip contains

-- Do (X : Interval e) and (Y : Interval e) overlap?
overlaps :: Interval i e => i -> i -> Bool 
x `overlaps` y = inf x <= sup y && sup x >= inf y

instance (Ord e) => Interval (e,e) e where
  inf (a,_) = a
  sup (_,b) = b

instance (Ord a) => Interval [a] a where
  inf = minimum
  sup = maximum

main :: IO ()
main = do
  putStrLn $ inf ["one","two","three"] -- will print "one"
  putStrLn $ sup ("first","second")    -- will print "second"

但是,正如評論員指出的那樣,這是完全不必要的。 最好使用Interval數據類型,而只使用Interval DoubleInterval Int等。我建議使用interval包裝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM