haskell - Haskell 中的组合

标签 haskell functional-programming functor

我最近正在学习 Haskell,我正在阅读 Learn You a Haskell 中的 Functors,我从中了解到

  • 功能 ((->)r)它采用一个参数,在某种程度上也是仿函数。
  • 作文(.)相当于 fmap

  • 所以根据我的理解, fmap 需要两个参数。第一个是要应用的函数,第二个是仿函数。

    然而,我对这个表达 (.) (.) (.) 感到困惑.这是两个组合的组合,类型为(b -> c) -> (a1 -> a2 -> b) -> (a1 -> a2 -> c)
    所以这就是我的怀疑。第一(.)有两个参数,第一个是组合函数本身。第二个参数也是组合函数。这样的组合函数不是仿函数。那么这是一个有效的表达方式吗?

    我确定我在这里遗漏了一些东西。有人可以填补空白并帮助我了解表达式的正确性吗?

    最佳答案

    忽略 Functor ((->) r) 的实例;这无关紧要。这里只有两点很重要: (.) 的类型,即

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

    ,以及函数应用程序保持关联的事实。后者意味着 (.) (.) (.)((.) (.)) (.) 相同.

    让我们先试着找出 (.) (.) 的类型(最左边的,如果你愿意的话)。让我们写第一个(.)的类型如 (b1 -> c1) -> (a1 -> b1) -> a1 -> c1第二个为 (b2 -> c2) -> (a2 -> b2) -> a2 -> c2 .我们将第一个应用到第二个,这给了我们 b1(b2 -> c2)c1(a2 -> b2) -> a2 -> c2 .因此我们有
    (.) (.) :: (a1 -> (b2 -> c2)) -> a1 -> ((a2 -> b2) -> a2 -> c2)
    

    可以简化为
    (.) (.) :: (a1 -> b2 -> c2) -> a1 -> (a2 -> b2) -> a2 -> c2
    

    现在让我们将此应用于最后一个 (.) (最右边的,如果你愿意的话)。如果有签名(b3 -> c3) -> (a3 -> b3) -> a3 -> c3 ,然后我们看到 a1必须是 (b3 -> c3) , b2必须是 (a3 -> b3)c2必须是 a3 -> c3 .因此,
    ((.) (.)) (.) :: (b3 -> c3) -> (a2 -> (a3 -> b3)) -> a2 -> a3 -> c3
    

    这与
    ((.) (.)) (.) :: (b3 -> c3) -> (a2 -> a3 -> b3) -> (a2 -> a3 -> c3)
    

    如果您进行一些重命名,这与您在问题中的情况相同。

    关于haskell - Haskell 中的组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28657765/

    相关文章:

    multithreading - Haskell 中的多核编程 - Control.Parallel

    scala - 定义自引用 Scala 类(递归类)

    data-structures - 纯函数式编程语言中的双向链表

    recursion - 如何停止递归?

    haskell - 是否有基于终端及其祖先映射递归数据类型的名称?

    c++ - 如果一个线程正在执行的仿函数被移动会发生什么?

    haskell - 如何捕获并忽略 Haskell 中的错误调用

    haskell - 如何在haskell列表中存储高阶函数数据?

    scala - scalaz 中的笛卡尔积遍历

    c++ - 模板函数+仿函数参数,为什么仿函数没有内联?