Elm 中的通用模式匹配

Generic pattern matching in Elm

我正在尝试构建一个通用映射函数,该函数将从联合类型中提取可能的内部类型,对内部值应用转换并将其映射回外部类型。

问题是,我需要一种方法来区分外部类型的特定值是否具有内部类型。

如果下面的代码实际编译了,它对我有用,但 Elm 不允许在模式匹配中使用常量。 (constructor第4行编译失败)

还有其他方法可以做到吗?

map : (inner -> outer) -> (inner -> inner) -> outer -> outer
map constructor func current =
    case current of
        constructor child ->
            constructor (func child)

        _ ->
            current

不,不幸的是 Elm 没有办法通用地表达这种东西,你需要为每个自定义类型编写一个特定的版本。

你可以看看 elm-accessors 图书馆。有了它,您将需要为您的每个类型构造函数定义一个 Relation (这非常简单)。但是之后你就可以自由地使用一个很好的旧 List.map 来映射任何构造函数!

这是一个用法示例:

type FooBar a b
  = Foo a
  | Bar b

items =
   List.map
     (over (foo << try) ((+) 1)           -- affects only "Foo"s
      << 
      over (bar << try) (\b -> b ++ "!")) -- affects only "Bar"s
     [Foo 1, Bar "a", Foo 10]
-- = [Foo 2,Bar "a!",Foo 11]

这里是live version (Ellie).