【问题标题】:Scala only language with overloaded extractors?Scala 仅具有重载提取器的语言?
【发布时间】:2025-12-30 17:55:10
【问题描述】:

至少在某些 ML 家族语言中,您可以定义可以执行模式匹配的记录,例如http://learnyouahaskell.com/making-our-own-types-and-typeclasses - 基本思想是您使用命名字段定义记录类型,使用这些字段作为参数自动创建构造函数,以便您可以创建该类型的记录,并使用这些字段作为参数自动创建提取器,以便您可以对该类型的记录进行模式匹配。

Scala 更进一步,允许存储在记录中的字段、构造函数参数和提取器参数相互解耦,例如http://daily-scala.blogspot.com/2009/11/overloaded-unapply.html - 在这方面,它实现了支持面向对象和函数式编程的目标。 (当然,面向对象的语言通常允许将存储的字段和构造函数参数解耦,尽管它们通常没有提取器。)

是否有其他语言具有模式匹配并允许这种解耦?

有没有关于这种脱钩的利弊的文章?

【问题讨论】:

  • Haskell 是 ML 家族语言吗?
  • 没用过,但是 Haskell 的观点很相似
  • 当然,像Scheme这样的动态语言在没有语言支持的情况下允许这样做,但我不知道是否有人使用它
  • @Owen 动态与它没有任何关系。人们已经编写了 OCaml 宏来提供视图模式而不需要语言的支持,并且 OCaml 是静态的。尽管是“动态的”,但 Mathematica 无法表达这一点。
  • @JonHarrop 确实没有必要,但这是一种方法。 (考虑例如红宝石,R)

标签: scala f# programming-languages functional-programming pattern-matching


【解决方案1】:

我承认我没有 100% 的背景知识来理解您的问题,但我可以说 F# 有一个名为“Active Patterns”的功能,它似乎可用于构建与您的问题相同的功能daily-scala链接演示。

那是你要找的附近吗?

【讨论】:

    【解决方案2】:

    不,F# 也提供该功能。

    第二篇中的例子可以使用Partial Active Patterns实现:

    let (|String|_|) = function "s" -> Some "yay" | _ -> None
    let (|Int|_|) = function 1 -> Some "hmm" | _ -> None
    
    let (|StringList|_|) = function "x" -> Some [1; 2; 3] | _ -> None
    let (|IntList|_|) = function 1 -> Some ["one"; "two"] | _ -> None
    
    match 1 with 
    | Int s -> printfn "%O" s 
    | _ -> printfn "Unmatched"
    
    match "s" with 
    | String s -> printfn "%O" s 
    | _ -> printfn "Unmatched"
    
    match "x" with 
    | StringList [x; y; z] -> printfn "%O" (x, y, z) 
    | _ -> printfn "Unmatched"
    
    match 1 with 
    | IntList [x; y] -> printfn "%O" (x, y) 
    | _ -> printfn "Unmatched"
    

    Active Patterns 是一种强大的技术,您甚至可以用recursive 的方式编写它。它与模式匹配的结合为解构数据提供了一个方便的工具包。但是,模式匹配并不详尽,因此您必须使用通配符 (_) 作为最后一个模式。

    【讨论】:

      【解决方案3】:

      作为参考,Don Syme(F# 的发明者)写了一篇关于 F# 的“Active Patterns”的论文:Extensible Pattern Matching Via a Lightweight Language Extension – Syme, et al.

      【讨论】:

        【解决方案4】:

        类型函数式语言中的一流模式由来已久。

        在 Haskell 领域,我们将 -XViewPatterns 扩展用于编程模式。

        第一个真实视图模式可以追溯到 Phil Wadler 1987 年在 views 上的论文

        【讨论】: