需要帮助来理解这个函数组合是如何工作的

Need help to understand how this function composition works

我可以毫无问题地理解这行代码

let f s = filter (isDigit.head) (groupBy (on (==) isDigit) s)

当我调用 f "123abc345" 时,它 returns ["123", "345"]

但是我很难理解为什么下面这行代码是一样的

let g = filter (isDigit.head) . groupBy (on (==) isDigit)

这个组合是如何工作的?非常感谢!

函数组合运算符.定义如下:

(.) f g = \x -> f (g x)

或者,同样的中缀形式:

f . g = \x -> f (g x)

在英语中,这可以这样表达:两个函数的组合 fg 是另一个接受参数 x 的函数,将其传递给函数 g,然后将 g 的 return 值传递给函数 f

如果您查看第一个片段:

let f s = filter (isDigit.head) (groupBy (on (==) isDigit) s)

如果你足够细心,你会发现它是一个接受参数 s 的函数,将其传递给函数 groupBy (on (==) isDigit),然后将 return 值传递给函数 filter (isDigit.head)

根据我上面的解释,它可以表示为两个函数的组合 - filter (isDigit.head)groupBy (on (==) isDigit),这就是你的第二个代码段。

首先是你的代码,供参考:

let f s = filter (isDigit.head)  (groupBy (on (==) isDigit) s)
let g   = filter (isDigit.head) . groupBy (on (==) isDigit)

(我对其进行了稍微格式化以强调相似之处。)

为了帮助我们,现在让我们为您定义的函数定义一些同义词:

let whereFirstIsDigit = filter (isDigit.head)
let groupByDigit      = groupBy (on (==) isDigit))

现在我们可以将原来的函数重写如下:

let f s = whereFirstIsDigit  (groupByDigit s)
let g   = whereFirstIsDigit . groupByDigit

现在让我们看看这里发生了什么。 f 获取 s,将其提供给 groupByDigit,然后将其结果提供给 whereFirstIsDigit。但是(比如)x . y 的函数组合被定义为将其输入提供给 y,然后将结果提供给 x 的函数!所以这两个功能是一样的。