gpt4 book ai didi

haskell - 比较 Haskell 中的函数

转载 作者:行者123 更新时间:2023-12-03 15:23:04 24 4
gpt4 key购买 nike

有没有办法比较 Haskell 中的两个函数?

我的想法是答案是否定的,因为函数不会派生 Eq 类型类。但是我正在尝试编写一个非常微不足道的函数,这似乎是一种正常的事情:

search :: ((Enum a) => a -> a) -> Card -> [Card]
search op x list = if (op == succ && rank x == King) ||
(op == pred && rank x == Ace)
then []
else let c = [ n | n <- list, rank n == op (rank x)]
in if length c == 1
then x : search op (head c) list
else []

错误信息:
No instance for (Eq (Rank -> Rank))
arising from a use of `=='

基本上,它要么向上或向下搜索卡片列表,以寻找与 x 中的下一张或上一张排名卡片匹配的卡片,从而构建一个列表。通过将“pred”或“succ”函数作为运算符,它可以向前和向后工作。但是,我需要检查它是否不会超出枚举范围,否则会引发异常。

所以我正在寻找一种方法来防止异常或解决这个问题!

任何其他关于改进代码的指针也将不胜感激:)

感谢所有伟大的提示,这是我提出的解决方案(真的从每个答案中吸取了一点!):

编辑:下面的正确解决方案:
 maybeSucc x | x == maxBound = Nothing
| otherwise = Just (succ x)
maybePred x | x == minBound = Nothing
| otherwise = Just (pred x)

-- takes a list of cards which have a rank one op than x
-- only if there is exactly one is it sequential, otherwise end matching
search :: (Rank -> Maybe Rank) -> Rank -> [Card] -> [Card]
search op x list = case filter (\n -> Just (rank n) == op x) list of
[y] -> y : search op (rank y) list
_ -> []

测试:
*Main> let cards = [Card Ace Heart, Card Two Club, Card Three Spade, Card Five Club, Card Four Diamond]

*Main> search maybeSucc Two cards

[Three of Spades,Four of Diamonds,Five of Clubs]

*Main> search maybePred Three cards

[Two of Clubs,Ace of Hearts]

最佳答案

无用的答案

没有也永远不会有一种方法来比较两个函数是否相等。有一个数学证明,一般来说这是不可能的。

“实用”方法要么取决于编译器的内部工作(例如,如果两个函数在内部由相同的内存地址表示,则它们是否相等),或者没有预期的帮助。
succ == (+1) 的预期结果是什么?让 succ == (+a) 中的 a == 1 怎么样?

我想不出一种方法来为总是有意义的函数定义 (==),我相信其他人也不能。

与问题无关的事情

类型签名缺少返回类型。

您的函数有 rank 2 类型,这不是标准的 Haskell 98,更重要的是,在这种情况下不是必需的。您不关心传入的函数是否可以处理任何 Enum 类型,您只关心它是否适用于 Rank:

search :: (Rank -> Rank) -> Card -> [Card] -> [Card]   -- much simpler.

我会尝试更频繁地使用案例,如果/那么更少。特别是,我会写:
case [ n | n <- list, rank n == op (rank x)] of
[y] -> x : search op y list -- length == 1
_ -> [] -- otherwise

我的真实答案

您的函数基本上只适用于 op 的两个不同值,但它的类型并没有这么说;这不适合我。

你可以用老式的方式来做:
data Direction = Succ | Pred deriving(Eq)

search :: Direction -> Card -> [Card] -> [Card]
search dir x list = if (dir == Succ && rank x == King) ...
... let op = case Direction of Succ -> succ ; Pred -> pred
in ...

或者您可以使参数更通用,并传递一个可能会正常失败的函数(通过返回 Nothing):
maybeSucc x | x == maxBound = Nothing
| otherwise = Just (succ x)

search :: (Rank -> Maybe Rank) -> Card -> [Card] -> [Card]
search op x list = case op (rank x) of
Nothing -> []
Just theRank -> case [ n | n <- list, rank n == theRank ] of ...

关于haskell - 比较 Haskell 中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4328620/

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