gpt4 book ai didi

haskell - 如何确定一个 Enum 值是否是另一个 Enum 值的后继值?

转载 作者:行者123 更新时间:2023-12-02 02:04:50 26 4
gpt4 key购买 nike

我正在尝试编写一个函数来告诉我是否有一个 Enum是另一个的继任者。这是我的第一次尝试:

isSuccessorOf x y = x == succ y
看起来有道理。让我们尝试一下:
λ> isSuccessorOf 3 2
True
λ> isSuccessorOf 1 5
False
λ> isSuccessorOf 3 (maxBound :: Int)
*** Exception: Prelude.Enum.succ{Int}: tried to take `succ' of maxBound
哎呀。那应该是 False .让我们确保我们不会尝试做 succ maxBound :
isSuccessorOf x y = y /= maxBound && x == succ y
让我们再试一次:
λ> isSuccessorOf 3 (maxBound :: Int)
False
λ> isSuccessorOf 3 (2 :: Integer)
<interactive>:2:1: error:
• No instance for (Bounded Integer)
arising from a use of ‘isSuccessorOf’
• In the expression: isSuccessorOf 3 (2 :: Integer)
In an equation for ‘it’: it = isSuccessorOf 3 (2 :: Integer)
嗯,现在它只适用于有界类型。我想避免为无界和有界 Enum 使用单独的函数s,特别是如果在编译时没有任何东西可以阻止您在有界类型上使用无界函数。让我们使用 Ord改为约束:
isSuccessorOf x y = x > y && x == succ y
让我们尝试一下:
λ> isSuccessorOf 3 (maxBound :: Int)
False
λ> isSuccessorOf 3 (2 :: Integer)
True
但现在我在做一个毫无根据的假设。让我们再尝试一件事(注意:这取决于 Down 具有 Enum 实例,它仅在 GHC 8.10 中具有):
λ> import Data.Ord (Down(..))
λ> let delisleFreezing = Down 150
λ> isSuccessorOf (succ delisleFreezing) delisleFreezing
False
嗯,这不太理想。
那么有没有什么方法可以完成这个看似简单的任务,而没有这三个缺陷之一呢?
  • 对于不是 Bounded 的类型编译失败
  • Bounded 类型的底部
  • succ x > x 的类型给出错误答案不持有
  • 最佳答案

    也许更安全的检查方法是使用 enumFromTo ,并检查列表的第二项是否是我们正在寻找的后继项。我们可以,像 you say ,只需对具有两个元素的列表进行模式匹配,我们不需要检查第二个元素是否确实是 y :

    isSuccessorOf :: Enum a => a -> a -> Bool
    isSuccessorOf y x
    | [_,_] <- [x .. y] = True
    | otherwise = False

    或者我们可以,例如 @chi says使用它来查看是否有继任者:
    succMaybe :: Enum a => a -> Maybe a
    succMaybe x = case [x ..] of
    (_:z:_) -> Just z
    _ -> Nothing

    关于haskell - 如何确定一个 Enum 值是否是另一个 Enum 值的后继值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61688753/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com