【问题标题】:Function application function in HaskellHaskell中的函数应用函数
【发布时间】:2013-07-31 03:30:33
【问题描述】:

假设我有一个函数列表

functions = [f, g, h]

每一个类型为a -> a

我也有一个值列表,比如数字,但任何东西都应该在这里工作

vals = [1,2,3]

我想将functions中的每个函数都应用到vals中对应的值

我的第一反应是使用 lambda 和 zipWith 之类的:

zipWith (\f v -> f v) functions vals

但坦率地说,这看起来很丑陋,在 Haskell 这样的好语言中并不是我所期望的。功能应用功能听起来像是解决方案。有这样的事吗?我是否遗漏了什么并且有更好的解决方案来解决我的问题?实际上,我最终为 Project Euler 解决方案编写了这个构造。它有效,但我不喜欢它。

【问题讨论】:

    标签: haskell higher-order-functions


    【解决方案1】:
    zipWith ($) f v
    

    $ 是函数应用程序。它具有特别低的优先级这一事实有时会让人陷入循环。

    【讨论】:

      【解决方案2】:

      很奇怪,

      zipWith id functions vals
      

      也可以!

      但是,真的,zipWith ($) 是正确的写法。

      【讨论】:

      • @JuanPablo 因为$ 实际上只是id,专门用于仅处理函数(并且具有非常低的优先级和中缀符号)。 $ 的类型,因为它把一个函数应用到一个参数,必须是 (a -> b) -> a -> b。请记住,所有 Haskell 函数都是“真正的”一元的(或等效地,-> 关联到右侧),与(a -> b) -> (a -> b) 具有相同的类型。这意味着它接受任何类型的函数并为您提供相同类型的函数;只是id :: a -> a 的一个特例,它接受任何类型的值并为您提供相同类型的值。
      • 另一种看待它的方式:使用zipWith id 意味着每个结果元素都由id f v 计算,id f 等于f 所以id f v 等于f v。跨度>
      【解决方案3】:

      这是另一个可能会让你思考的选项。

      >>> import Control.Applicative
      >>> let functions = ZipList [(+1), (*2), (*10)]
      >>> let values    = ZipList [1, 2, 3]
      >>> getZipList (functions <*> values)
      [2, 4, 30]
      

      ZipList 只是列表的包装。 &lt;*&gt;ZipList 的定义是“通过依次将每个函数应用于参数来压缩函数列表(左侧)和参数列表(右侧)”。

      这与&lt;*&gt; 对常规列表的定义形成对比,后者表示“从这两个列表中获取每对可能的(函数、参数)并将函数应用于参数”。

      【讨论】:

        猜你喜欢
        • 2014-11-01
        • 2010-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-03
        相关资源
        最近更新 更多