【问题标题】:Haskell record pattern matchingHaskell 记录模式匹配
【发布时间】:2016-10-29 09:13:48
【问题描述】:

我正在寻找一种在不需要实际数据时简化函数模式的方法:

data X = A | B String | C Int Int String
myfn :: X -> Int
myfn A = 50
myfn (B _) = 200
myfn (C _ _ _) = 500

有没有办法制作一个更简单的模式来匹配 C,只是丢弃这些值?

hsdev 添加了一个提示“提示:使用记录模式”,但谷歌并没有帮助我。

【问题讨论】:

    标签: haskell pattern-matching record algebraic-data-types


    【解决方案1】:

    您可以像这样使用记录模式:

    data X = A | B {name :: String} | C {x::Int, y::Int, name::String}
    
    myfn :: X -> Int
    myfn A = 50
    myfn B{} = 200
    myfn C{} = 500
    

    记录模式允许您为构造函数的字段命名。 您还可以执行以下操作:

    myfn C{name=n} = length n
    

    所以你可以看到你只能在你需要的特定字段上进行模式匹配。

    注意:即使是不使用记录语法的数据类型,您也可以使用 empty 记录模式:

    data A = A Int | B Int Int
    
    myfn A{} = 1
    myfn B{} = 2
    

    这很好。 还有许多与记录模式相关的其他扩展:

    • RecordWildCards 允许您编写类似C{..} 的内容,它等价于模式:C{x=x, y=y, name=name},即它匹配所有字段并且您现在在x 范围内具有与@ 匹配的值987654328@字段等

    • NamedFieldPuns 允许您将C{name} 写成与C{name=name} 等效,这样name 现在就在范围内并包含与name 字段匹配的值。

    请记住,使用记录模式不会阻止您以位置方式使用构造函数,因此您仍然可以编写:

    myfn (B _) = 200
    

    它只是添加功能。

    【讨论】:

    • 太好了,谢谢。我实际上尝试了 C{_} 和 C{..},但无济于事。一个字太多了。 ^^
    • 遗憾的是,Google 对“haskell 记录模式”的帮助不大。我已经重命名了这个问题,也许这会让其他人更容易发现它。
    • @theduke:还要注意,即使您将 B 声明为普通的非记录数据类型,您也可以使用空记录模式 (B{})。
    • @Lii 这是我没有想到的。我会在答案中添加提及。
    • @Lili 感谢您的指出。不过,对我来说,无论如何,从答案中就很明显了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    • 2021-05-22
    • 2011-10-29
    • 1970-01-01
    • 2017-05-08
    • 2019-03-01
    • 2017-10-12
    相关资源
    最近更新 更多