haskell R 中函数调用参数值的样式模式匹配

haskell style pattern matching of parameter values for function calls in R

在R中,是否可以根据参数值进行函数模式匹配ala Haskell?

即如果参数 x 是 ='foo', 运行 函数的一个版本,如果 x 是 'bar', 运行 另一个版本?显然这可以在必要时使用 if 语句来完成,但我想知道是否有更多的 'functional' 方法。

例如,要自动进行这种函数选择(foo1 与 foo2)而不需要 ifelse 语句来进行条件处理:

foo1 <- function(a) {
    paste0(a, 'foo1')
}

foo2 <- function(a) {
    paste0('baz', a, 'foo2')
}

x <- 'barp'
value <- ifelse(x == 'barp', foo1(x), foo2(x))

这可以根据对象的 "class" 来完成,但不是值。我对 Haskell 不是很熟悉,但我虽然 Haskell 也在 class/type 上调度而不是实际值?这是 R 实现:

> foo <- function(a) UseMethod("foo")
> foo.1 <- function(a) paste(a, 'foo1')
> foo.2 <- function(a) paste('baz', a, 'foo2')
> 
> obj_1 <- structure("hello world", class="1")
> obj_2 <- structure("hello world", class="2")
> 
> foo(obj_1)
[1] "hello world foo1"
> foo(obj_2)
[1] "baz hello world foo2"

这只会根据第一个参数的 class 进行分派。如果您想基于多个参数进行分派,可以使用 S4 方法。

对于一般代数数据类型,您可以定义自己的匹配函数助手。这些有时被称为 "eliminators",实质上是将您的 ADT 值转换成它们的 Church 编码。

例如,让我们翻译这个 Haskell 代码片段:

x = Just 3
y = Nothing
a = case x of Nothing -> 42 ; Just w -> w+100
b = case y of Nothing -> 42 ; Just w -> w+100

结果是:

# eliminator
matchMaybe <- function(x,kn,kj) {
   ifelse(x[[1]]=='Nothing', kn(), kj(x[[2]]))
}

# tests
x <- list('Just', 3)
y <- list('Nothing')
a <- matchMaybe(x
               ,function() { 42 }
               ,function(w){ w+100 })
b <- matchMaybe(y
               ,function() { 42 }
               ,function(w){ w+100 })

但是请注意,深度 模式匹配很难以这种方式翻译。 也就是说,在 Haskell 中你可以做类似

的事情
case x of Just 10 -> 22 ; Nothing -> 42 ; Just w -> w+100

其中您同时匹配 Just 构造函数和内部 10。这不能以方便的方式编码。

对于字符串,如 OP 示例中所示,可能的消除器可能是:

match <- function(x,v,kt,ke) {
   ifelse(x==v, kt(),ke(x))
}

r <- match('foo'
     , 'bar', function() { "then" }
     ,        function(x) { "else" })

另外请记住,我对 R 语言不是很流利,因此可能有更好的方法。