首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >模式匹配不同输入相同输出哈斯克尔

模式匹配不同输入相同输出哈斯克尔
EN

Stack Overflow用户
提问于 2019-02-08 15:59:54
回答 2查看 318关注 0票数 0

我有一个函数,输出一个月的天数,需要改变守卫和使用模式匹配。`

代码语言:javascript
运行
复制
daysInMonth :: Int -> Int
daysInMonth m

    | m == 4 || m == 6 || m == 9 || m == 11 = 30
    | m == 2 = 28
    | m > 12 || m < 0 = error "Month does not exist"
    | m == m = 31

“我能把第4、6、9和11个月放在同一条线上吗?我要如何或必须把它们放在不同的线上呢?”

EN

回答 2

Stack Overflow用户

发布于 2019-02-08 16:19:55

可以使用ViewPatterns扩展来匹配应用于参数的任意函数的结果。(这可能不符合转换为模式匹配的精神,但我要说,它满足了任务的要求。)

代码语言:javascript
运行
复制
{-# LANGUAGE ViewPatterns #-}

daysInMonth :: Int -> Int
daysInMonth (\x -> x < 0 || x > 12 -> True) = error "Month does not exist"
daysInMonth ((`elem` [4, 6, 9, 11]) -> True) = 30
daysInMonth 2 = 28
daysInMonth _ = 31

这也有助于进行简单的查找。(关联列表不完整以节省空间。)

代码语言:javascript
运行
复制
daysInMonth :: Int -> Int
daysInMonth (flip lookup [(1,31), (2,28), (3,31), ...] -> Just d) = d
daysInMonth _ = error "Month does not exist"

在这里,我们应用lookup返回一个Maybe Int值,并将其与Just d匹配。如果查找成功(对于有效的月份号应该是这样),则返回值d。如果lookup返回Nothing,则模式匹配失败,我们将尝试下一个模式匹配,它为它所看到的任何输入调用error

(当然,这更简单地写成了daysInMonth = maybe (error "...") id . flip lookup [...],而不是求助于ViewPatterns扩展,但我认为这是视图模式如何工作的一个很好的例子。)

票数 2
EN

Stack Overflow用户

发布于 2019-02-09 05:39:17

不知道我是否理解这个问题,让我试试看。

如果您确实需要删除保护,您可以匹配每个情况的输入值。但正如您所看到的,它将大大减少readability

在使用模式匹配时要小心,确保包含所有可能的情况。

下面的代码不是一个很好的例子,只是为了说明它是可行的。

代码语言:javascript
运行
复制
daysInMonth :: Int -> Int

-- | m == 4 || m == 6 || m == 9 || m == 11 = 30
daysInMonth 4 = 30
daysInMonth 6 = 30
daysInMonth 9 = 30
daysInMonth 11 = 30

-- | m == 2 = 28
daysInMonth 2 = 28

-- | m > 12 || m < 0 = error "Month does not exist"
-- | m == m = 31
daysInMonth m = if (m > 12 || m < 0)
                then error "Month does not exist"
                else 31
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54596132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档