当前位置: 首页 > 知识库问答 >
问题:

Haskell中的反向函数合成

段干长恨
2023-03-14
countWhere :: (a -> Bool) -> [a] -> Int
countWhere predicate xs = length . filter predicate $ xs

在JavaScript中,该代码如下所示:

function countWhere(predicate, xs) {
    return xs.filter(predicate).length;
}

正如您所看到的,函数组合与JavaScript中的链接方法非常相似。我真的很喜欢链接方法从左到右读取的方式。在Haskell中,我可以使用control.arrow中的>>>函数和反向函数html" target="_blank">应用程序执行类似的操作,如下所示:

import Control.Arrow

($>) :: a -> (a -> b) -> b
($>) = flip ($)

countWhere :: (a -> Bool) -> [a] -> Int
countWhere predicate xs = xs $> filter predicate >>> length

现在我想用点自由样式来写这个函数。使用函数组合,我将把它写如下:

(.:) :: (b -> c) -> (d -> a -> b) -> d -> a -> c
(.:) = (.) (.) (.)

countWhere ::  (a -> Bool) -> [a] -> Int
countWhere = length .: filter
(.:) :: (b -> c) -> (d -> a -> b) -> d -> a -> c
(.:) = (.) (.) (.)

(:.) :: (d -> a -> b) -> (b -> c) -> d -> a -> c
(:.) = flip (.:)

countWhere :: (a -> Bool) -> [a] -> Int
countWhere = filter :. length
(:.) = flip $ (.) (.) (.)

-- instead of

(:.) = (>>>) (>>>) (>>>)

函数组合的美妙之处在于它可以与自身组合,形成如上所示的“高阶函数组合”。因此,尽管它的类型签名直观上是向后的,但实际上是向前的,这解释了为什么f。g=\x->f(Gx)而不是f。g=\x->g(fx)

这就引出了我的实际问题:有没有办法用反向函数组合(即>>>)来定义“高阶反向函数组合”,而不是翻转对应的“高阶函数组合”?

我在寻找一个可以从范畴理论或其他数学分支中找到的答案。

共有1个答案

商曦
2023-03-14

所以这里有一个伪无点答案

(.:.) :: (a -> b -> c) -> (c -> d) -> a -> b -> d
f .:. g = (,) f >>> app >>> (>>> g)

这依赖于范畴理论中所谓的“指数”。Expontentials基本上提供了两个函数

curry :: ((a, b) -> c, a) -> c^b
eval  :: (c^b, b)         -> c

它或多或少是curryuncurry($)的通用版本。

(.:.) = (. flip (>>>)) . (>>>) . (>>> app) . (,)
(.:.) = (,) >>> fmap app >>> (>>>) >>> ((<<<) >>>)
(.:.) = uncurry >>> (>>>) >>> (>>>curry)
 类似资料:
  • 函数组合是将一个函数的输出用作另一个函数的输入的过程。在数学中,合成用表示,其中是一个函数,其输出用作另一个函数(即)的输入。 如果一个函数的输出类型与第二个函数的输入类型匹配,则可以使用这两个函数来实现函数组合。我们使用点运算符()在Haskell中实现函数组合。 看下面的示例代码。演示如何使用函数组合来计算输入数字是偶数还是奇数。 在这里,在函数中,同时调用了两个函数和。编译器将首先以作为参数

  • ; ; ; 在2.中,设3。;因此,应为,,替换为1。,为,应为 但是,应该彼此相等,?如何使两者在GHCi中相互适应,它似乎用或代替了,那么它是如何前进的呢?

  • 我们从右到左都知道并爱/恨作文: 什么是自然/从左到右组合的“最标准”操作符(如在某种公共库中):

  • 作为一个Haskell新手,我不明白为什么表达式抛出异常和函数组合必须与运算符一起应用-它右边的表达式不需要进一步计算,因为它只是一个。编译它的另一种方法是将在括号中,但是与,那么为什么把它放在括号中可以编译表达式呢?

  • 问题内容: 如果我有一个带字符( )的字符串,则此字符串的函数将返回。 有没有办法进行反向操作:如果我有string (带字符 ),我需要获得string 。 问题答案: 我认为您正在寻找的是:

  • 函数在Haskell中起主要作用,因为Haskell是一种函数式编程语言。与其他语言一样,Haskell确实具有自己的函数定义和声明。 函数声明由函数名称,其参数列表以及其输出组成。函数定义是实际定义函数的地方。让我们看看一个添加函数的示例,以详细了解此概念。 在这里,在第一行中声明了函数,在第二行中,我们编写了实际的函数,该函数将带有两个参数并产生一个整数类型的输出。 与大多数其他语言一样,Ha