![](/img/trans.png)
[英]Why isn't the Fractional typeclass inherently orderable in 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 Double
, Interval Int
等。我建议使用interval包装。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.