【问题标题】:Function composition in Haskell exampleHaskell 示例中的函数组合
【发布时间】:2017-09-20 15:33:40
【问题描述】:

假设 b 是一个字符串列表并考虑,

map (map (\a -> ((head a), (length a))) . group . sort) (transpose b)

我知道上面每个单独的函数的作用,但我无法看到结果是如何组合的。我将如何弄清楚这条线上的函数运行的顺序,使用哪些参数?

具体来说,我好像明白(map (\a -> ((head a), (length a))) . group . sort)是外映射的第一个参数,(transpose b)是外映射的第二个参数。

但是内部地图的参数是什么?内部地图似乎只有一个参数:(\a -> ((head a), (length a))) . group . sort)。第二个参数(要应用的列表,按元素,第一个参数中的函数)在哪里?

【问题讨论】:

标签: haskell function-composition


【解决方案1】:

你注意到的被称为currying,它是 Haskell 函数的许多伟大(或可能不是)方面之一。这是你的代码:

map (map (\a -> ((head a), (length a))) . group . sort) (transpose b)

让我们检查一下第一个map的类型:

map (\a -> ((head a), (length a))) :: [[a]] -> [(a, Int)]

我们通过输入这个来做到这一点

:t map (\a -> ((head a), (length a)))

进入ghci

所以知道我们知道它是一个函数。它接受[[a]] 类型的元素并返回[(a, Int)]。给出map函数的类型是

map :: (a -> b) -> [a] -> [b]

这很好。我们已经给了map 这是第一个参数,现在,它所需要的只是一个正确的列表。 map 刚刚发生的事情称为currying

现在让我们看看,我们通过(.) 函数将map“连接”到sortgroup

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

现在让我们稍微修改一下您的代码,以便更好地了解组合函数的情况。

map (\a -> ((head a), (length a))) . (group . sort)

我只是用括号分隔了groupsort。但是现在我们清楚地看到哪些元素充当了外部(.) 的参数。

我们有相关的地图和另一个功能,它是由另一个组合产生的。当我们省略最后一个参数时,我们再次有 currying

map (\a -> ((head a), (length a))) . (group . sort)
:: Ord a => [a] -> [(a, Int)]

最后,外部map 采用了上面的函数和一个列表(transpose b)

【讨论】:

    【解决方案2】:

    它是隐式给出的。如果你写:

    map (\a -> ((head a), (length a))) . group . sort
    

    这实际上是以下简称:

    \b -> (map (\a -> ((head a), (length a))) . group . sort) b
    

    相当于:

    \b -> map (\a -> ((head a), (length a))) $ group $ sort b
    

    或:

    \b -> map (\a -> ((head a), (length a))) (group (sort b))
    

    (.) :: (b -> c) -> (a -> b) -> a -> c 运算符,因此在某种管道中将两个函数组合在一起:

    (.) f g x = f (g x)
    

    因为我们这里写了三个用点分隔的函数:

       map (\a -> ((head a), (length a))) . group . sort
    -- \_________________ ______________/   \_ _/   \_ /
    --                   v                    v       v
    --                   f                    g       h
    

    我们定义了某种管道,首先通过h处理一个元素,然后通过g处理结果,最后通过f处理结果。

    【讨论】:

      【解决方案3】:

      点本身就是一个函数,定义如下:

      (f . g) x = f (g x)
      

      让我们在外部映射的第一个参数中使用这个等式:

      map (\a -> (head a, length a)) . group . sort
      = { definition of (.), with map (\a -> ...) as f and group . sort as g }
      \x -> map (\a -> (head a, length a)) ((group . sort) x)
      

      因此,map (\a -> ...) . group . sort 是一个函数,当应用于参数 x 时,将 (group . sort) x 作为参数提供给 map (\a -> ...)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-30
        • 2010-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多