首页 文章

为什么haskell中没有间隔类型类?

提问于
浏览
2

也许我没有找到正确的地方,但我找不到Haskell中的间隔类型类 . 在我看来,这种抽象在许多情况下都很有用,因为在许多领域中使用了区间 .

这也可以通过实现某种间隔结构的hackage上的不同包的数量来看出(list of interval packages) .

使用类型类实现不同类型的间隔(开放,封闭,...)会不会令人困惑,还是有其他概念可以帮助我构建自己的间隔,除了自己的数据类型?

1 回答

  • 0

    您可以使用-XFunctionalDependences-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 等 . 我推荐intervals包 .

相关问题