使用模式匹配重载函数?

Overloading Functions with Pattern Matching?

大家好Haskell粉丝们!

我所有的问题都是关于 -- OVERLOADED(?) FUNCTION -- 部分,为了完整起见,我将其余部分包括在内。

  1. 我想知道使用模式匹配来重载我的函数 order 是否有意义,就像我在下面的示例中所做的那样。

  2. 我还想知道 order 函数的第一个版本中第一个带有函数调用“checkBalance balance”的函数是否总是被执行(因为我没有为其指定模式)或从不(因为 Food 的所有模式都包含在下面的函数中)。

先谢谢初学者:)

-- TYPE DECLARATIONS --
data Spice = Regular | Medium | Hot
data Base  = Noodles | Rice
data Meat  = Duck | Chicken | Pork
data Sauce = Tomato | Meatballs | Carbonara

data Food  = Indian Spice | Pasta Sauce | Chinese Base Meat

data DeliveryOption = Pickup | Delivery

data DeliveryTime = Immediate | Later

type CreditBalance = Int

data Order = O Food DeliveryOption CreditBalance

data OrderStatus = Success | Pending | Declined

-- OVERLOADED(?) FUNCTION --
order :: (Order, CreditBalance) -> OrderStatus
order (O {}, balance)
  | not (checkBalance balance ) = Declined
  | ...

order (O Indian {} _ _, _)
  | ...

order (O Pasta {} _ _, _)
  | ...

order (O Chinese {} _ _, _)
  | ...

-- ANOTHER FUNCTION --
checkBalance :: CreditBalance -> Bool
checkBalance balance
  | balance > 100 = True
  | otherwise = False

我看不出该函数定义有任何问题。

函数子句按顺序尝试,所以第一个带有 checkBalance 的分支总是先被尝试,然后是下一个守卫,依此类推,如果第一个守卫的 none匹配组,则尝试下一组(O Indian {} _ _)。

如果第一组的守卫穷尽,那么下面的其他分支就无法到达,那就说明有问题,但不详细就不好说了。

-- OVERLOADED(?) FUNCTION --
order :: (Order, CreditBalance) -> OrderStatus
order (O {}, balance)
  | not (checkBalance balance ) = Declined
  | ...

上面的模式将涵盖所有情况,低于它的任何东西都没有机会检查。

原因是Order只有一个构造函数,即O,而(O {})匹配所有可能的参数给O构造函数。元组的另一个成员只是一个简单的 Int,它始终匹配。

由于模式是从上到下匹配的,并且会选择第一个匹配的模式,因此它们在代码中的定义顺序很重要。如果您将尽可能广泛的模式放在顶部,那么下面更具体的模式将永远没有机会匹配。

至于重载函数,我可以想到如何(滥用)使用模式匹配来模仿 OOP 中的函数重载,但是您还需要(滥用)使用数据声明和整个类型系统来让他们屈服于这样的想法,这只会让事情变得更糟。