代码之家  ›  专栏  ›  技术社区  ›  Fragsworth

Haskell函数组成

  •  25
  • Fragsworth  · 技术社区  · 17 年前

    我在读书 this 关于haskell的教程。它们定义 功能组成 如下所示:

    (.)                     :: (b->c) -> (a->b) -> (a->c)
    f . g                   = \ x -> f (g x)
    

    没有提供任何例子,我相信这些例子会启发我这里所定义的东西。

    有人能提供一个简单的例子(带解释)说明如何使用函数组合吗?

    6 回复  |  直到 8 年前
        1
  •  44
  •   Tom Lokhorst    17 年前

    函数组合是将两个函数“组合”为一个函数的方法。下面是一个例子:

    假设您具有以下功能:

    even :: Int -> Bool
    not :: Bool -> Bool
    

    你想定义你自己的 myOdd :: Int -> Bool 使用上面的两个函数。

    最明显的方法是:

    myOdd :: Int -> Bool
    myOdd x = not (even x)
    

    但使用函数组合可以更简洁地做到这一点:

    myOdd :: Int -> Bool
    myOdd = not . even
    

    这个 myOdd 函数的行为完全相同,但第二个函数是通过“粘合”两个函数而创建的。

    其中特别有用的一个场景是消除对显式lambda的需求。例如:

    map (\x -> not (even x)) [1..9]
    

    可重写为:

    map (not . even) [1..9]
    

    稍微短一点,出错的空间就少了。

        2
  •  30
  •   Apocalisp    8 年前

    有趣的侧记。函数组合在逻辑上等同于三段论:

    所有人都是凡人。苏格拉底是一个人。因此,苏格拉底是凡人。

    三段论将两个实质性的含义组合成一个:

    (Man => Mortal), (Socrates => Man), therefore (Socrates => Mortal)
    

    因此…

    (b -> c) -> (a -> b) -> (a -> c)
    

    …哪种类型的 . 功能。

        3
  •  13
  •   David Crawshaw    17 年前

    这个 作文 属于 f 和 g 是首先应用的函数 克 就其论点而言, F 返回的值 G . 然后返回 F .

    这个身份可能会启发我们:

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

    如果你有一个爪哇/ C背景,考虑这个例子:

    int f(int x);
    int g(int x);
    int theComposition(int x) { return f(g(x)); }
    
        4
  •  7
  •   Brian    17 年前

    这个例子是人为的,但是假设我们

    sqr x = x * x  
    inc x = x + 1
    

    我们要写一个计算x^2+1的函数。我们可以写

    xSquaredPlusOne = inc . sqr
    

    (意味着

    xSquaredPlusOne x = (inc . sqr) x
    

    这意味着什么

    xSquaredPlusOne x = inc(sqr x)
    

    因为f=inc,g=sqr)。

        5
  •  5
  •   MathematicalOrchid    14 年前

    函数组合是将两个或多个函数链接在一起的一种方法。它经常被比作壳体管道。例如,在一个Unix样式的shell中,您可能会编写类似

    cat foo.txt | sort -n | less
    

    这运行 cat ,将其输出馈送到 sort ,并将输出从 less .

    严格来说,这就像哈斯克尔 $ 操作员。你可以写一些像

    sum $ sort $ filter (> 0) $ my_list
    

    注意,与shell示例不同,它从右向左读取。所以我们从 my_list 作为输入,然后我们运行 filter 在它上面,然后我们 分类 然后我们计算 sum 其中。

    函数组合运算符, . 做了类似的事情。上面的示例生成 数 ;下面的示例生成 功能 :

    sum . sort . filter (> 0)
    

    请注意,我们并没有向其中输入列表。相反,我们刚刚创建了一个新函数,我们可以向该函数提供几个不同的列表。例如,您可以将此函数命名为:

    my_function = sum . sort . filter (> 0)
    

    或者您可以将它作为参数传递给另一个函数:

    map (sum . sort . filter (> 0)) my_lists
    

    你基本上可以在任何地方使用它,你可以使用任何其他类型的函数。它只是一种快速易读的表达方式,“我想把这些函数连接在一起”。

        6
  •  4
  •   Chris Lutz    17 年前

    从 HaskellWiki page on function composition:

    desort = (reverse . sort)
    

    现在 desort 是一个反向排序列表的函数。基本上, 解吸 把它的论点输入 sort ,然后从 分类 进入之内 reverse ,则返回。所以它对它排序,然后反转排序列表。

    推荐文章