gpt4 book ai didi

haskell - 模式匹配变量的范围

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

有一些类型Record :

type Day         = Integer
type Description = String
type Name = String
type PhoneNumber = String
type Year = Integer

data Month = January | February | March | April | May | June | July
| August | September | October | November | December
deriving (Eq, Ord, Enum, Show)
data Birthday = Birthday Month Day
deriving (Eq, Show)
data DatingDate = DatingDate Year Month Day
deriving (Eq, Show)

data Record = BirthdayRecord Name Birthday
| PhoneRecord Name PhoneNumber
| DatingRecord DatingDate Description
deriving (Eq, Show)

以及按日期过滤这些记录的函数:
getAssignment :: (Year, Month, Day) -> [Record] -> [Record]
getAssignment (year, month, day) = filter matchDate
where matchDate (BirthdayRecord _ (Birthday month day)) = True
matchDate (DatingRecord (DatingDate year month day) _) = True
matchDate _ = False
getAssignment 的这个定义由于错误而不正确:
warning: Defined but not used: `year'

实际上, year 让我有点意外。在 getAssignment 的模式匹配部分中和 yearmatchDate 的模式匹配部分中不一样。

那么, year 的范围边界在哪里?变量开始和结束?这是因为 where部分?

顺便说一句,这个错误可以通过使用 (year, month, day) 的一些冗余来避免。变量。
getAssignment' :: (Year, Month, Day) -> [Record] -> [Record]
getAssignment' date = filter (matchDate date)
where matchDate (_, m, d) (BirthdayRecord _ (Birthday month day)) =
month == m && day == d
matchDate (y, m, d) (DatingRecord (DatingDate year month day) _) =
year == y && month == m && day == d
matchDate _ _ = False

怎么可能改写?

最佳答案

范围是整个表达式(包括 where 子句中的定义),除了模式中的变量总是定义一个新的变量绑定(bind)。

您应该在内部绑定(bind)中使用不同的变量名,而不是重用相同的名称。

getAssignment :: (Year, Month, Day) -> [Record] -> [Record]
getAssignment (year, month, day) = filter matchDate
where matchDate (BirthdayRecord _ (Birthday month' day'))
= month == month' && day == day'
matchDate (DatingRecord (DatingDate year' month' day') _)
= year == year' && month == month' && day == day'
matchDate _ = False

重用变量名称以便它隐藏外部范围的变量称为遮蔽。如果您使用 -Wall,GHC 会在您这样做时发出警告。 (或 -fwarn-name-shadowing 仅启用此警告)。

编辑:对于您的特定功能,这可能是一种更清晰的编写方式:
getAssignment :: (Year, Month, Day) -> [Record] -> [Record]
getAssignment (year, month, day) = filter matchDate
where matchDate (BirthdayRecord _ birthday) = birthday == Birthday month day
matchDate (DatingRecord date _) = date == DatingDate year month day
matchDate _ = False

但是如果你想使用它,你不能避免给模式的一部分命名,即使只是为了将它与其他东西进行比较。

关于haskell - 模式匹配变量的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10057659/

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