【问题标题】:Understanding monadic function composition理解一元函数组合
【发布时间】:2019-08-05 04:46:43
【问题描述】:

我正在从“Learn You a Haskell for Great Good!”一书中学习 monad。米兰利波卡。我试图了解单子的结合律。从本质上讲,法律规定,当您拥有带有>>= 的一元函数应用程序链时,它们的嵌套方式无关紧要。

以下代码可以将a -> m b 类型的函数的结果传递给b -> m c 类型的函数:

(<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
f <=< g = (\x -> g x >>= f)

但是,对于下面的示例:

ghci> let f x = [x, -x]
ghci> let g x = [x*3, x*2]
ghci> let h = f <=< g
ghci> h 3
[9, -9, 6, -6]

f xg x 都是函数吗?似乎它们是具有不同 x 值而不是函数的列表。 let h = f &lt;=&lt; g 行在上面的代码中是如何工作的? fg 必须是函数,因为它们与 &lt;=&lt; 一起使用,但我不确定它们是什么。

【问题讨论】:

  • fg 是函数。 f xg x 是列表(假设范围内有变量 x;否则它们是错误)。

标签: list haskell monads function-composition kleisli


【解决方案1】:
f x = [x, -x]

这是普通的函数定义语法。我们正在定义一个新函数 f,写下它在应用于假设值 x 时会产生什么。

let(无论是作为语句还是let ... in ... 表达式)只是引入了一个可以进行定义的块,就像where。定义本身使用与全局相同的语法。

如果您知道如何通过编写来定义函数,例如plusOne n = n + 1 在一个文件中,那么这个语法是完全一样的(如果你不知道怎么做,那么我建议在你尝试理解单子函数组合之前阅读一些关于基本 Haskell 语法的介绍性教程)。

所以在这些定义之后 fg 是函数。 f xg x 没有任何意义,因为您没有 x 在范围内应用它们。

如果您在范围内确实有这样的值,那么f x 将是一个计算结果为列表的表达式,其中涉及调用函数f。说f xg x 是函数仍然是不正确的。

所以现在应该清楚let h = f &lt;=&lt; g 正在通过将&lt;=&lt; 运算符应用于fg 来定义一个新值h

【讨论】:

    【解决方案2】:

    没有什么比在一张纸上手工完成定义更能获得理解的感觉了。

    f x = [x, -x]也可以写成f = (\ x -&gt; [x, -x])。因此

      h 3 
    = {- by def of h -}
      (f <=< g) 3 
    = {- by def of (<=<) -}
      (\x -> g                   x >>= f               ) 3
    = {- by defs of f and g -}
      (\x -> (\ x -> [x*3, x*2]) x >>= (\ x -> [x, -x])) 3
    = {- by substitution -}
             (\ x -> [x*3, x*2]) 3 >>= (\ x -> [x, -x])
    = {- by substitution -}
                     [3*3, 
                      3*2]         >>= (\ x -> [x, -x])
    = {- by definition of (>>=) for [] -}
      concat [       (3*3)         &   (\ x -> [x, -x])  -- x & f == f x
             ,       (3*2)         &   (\ x -> [x, -x]) 
             ]
    = {- by definition of concat -}
                     (3*3)         &   (\ x -> [x, -x])
             ++      (3*2)         &   (\ x -> [x, -x]) 
    = 
      [9, -9, 6, -6]
    

    edit)有关图片以及对这些Kleisli 箭头 及其可组合性的更多讨论,请参阅this older answer of mine

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多