haskell - Map 函数将非函数作为第一个参数

标签 haskell

-- file: ch19/divby1.hs
divBy :: Integral a => a -> [a] -> [a]
divBy numerator = map (numerator `div`)

这是 O'reilly - Haskell 书中的代码摘录。

示例运行为,

ghci> divBy 50 [1,2,5,8,10]
[50,25,10,6,5]

令我困惑的是

  1. 为什么表达式中LHS上有两个变量divBynumerator:

    divBy numerator = map (numerator `div`)
    

最后为变量 divBynumerator 分配了什么值?

  • map 函数类型为 map::(a -> b) -> [a] -> [b]。 在上面的表达式中,参数numerator不是函数类型,并且 div 不是数组类型。但代码可以工作!!
  • 我在这里缺少什么?

    最佳答案

    关于 eta 转换和签名

    首先,我认为您错过了一些` :在 numerator `div` (是的,我认为所以吃了它们 - 你必须输入 `` numerator `div` `` 才能工作!)

    这个:

    divBy :: Integral a => a -> [a] -> [a]
    divBy numerator = map (numerator `div`)
    

    另一种写法

    divBy :: Integral a => a -> [a] -> [a]
    divBy = \ numerator -> map (numerator `div`)
    

    可以扩展为

    divBy :: Integral a => a -> [a] -> [a]
    divBy = \ numerator ns -> map (numerator `div`) ns
    

    如果您愿意,可以将参数放回左侧:

    divBy :: Integral a => a -> [a] -> [a]
    divBy numerator ns -> map (numerator `div`) ns
    

    这里可能更清楚 numerator是第一个参数(类型为 a )和 ns是第二个(类型为 [a] ),而 divBy当然是函数的名称。

    这是有效的,因为有一个名为 eta conversion 的东西这基本上是说你可以缩短 \x -> f x到只是f - 但有时要小心你run into trouble但它经常被用来写 point-free-style haskell 代码。

    你的问题

    What confuses me is

    why there are two variables on LHS divBy and numerator in the expression:

    divBy numerator = map (numerator `div`)
    

    答案:这些不是变量 - 第一个是您在此行中声明的函数的名称,第二个是它的第一个参数的名称。

    您可能想知道第二个去了哪里(见上文) - 简短的答案是:divBy实际上是一个需要 a 的函数并返回另一个函数 [a] -> [a]因此,只要您返回一个函数(并且您确实这样做了),您实际上只需给出一个参数。

    What values, the variables divBy and numerator are assigned at the end?

    回答:正如我所说divBy是您的函数的名称 - numerator将得到第一个参数,所以在

     λ> divBy 5 [1..10]
     [5,2,1,1,1,0,0,0,0,0]
    

    numerator5

    map function type is map :: (a -> b) -> [a] -> [b] In the above expression, the argument numerator is not a function type, and div is not of array type. But the code is working!!

    What am i missing here?

    基本上你缺少括号 - (numerator `div`)是所谓的section - 这确实是函数\n -> numerator `div` n - 将其视为在中缀的第二个参数处有一个 `div` :(免责声明:伪代码)(numerator `div` _) .

    所以(numerator `div`)确实是一个函数Integral a => a -> a所以它符合 map 的第一个参数.

    现在第二个在哪里?好吧,这又是与上面相同的故事:map (numerator `div`)是一个函数Integral a => [a] -> [a]这就是您的声明右侧缺少的内容 divBy numerator .

    我希望您能根据我在这个答案的第一部分中给您的内容来弄清楚。

    如果您有疑问,请发表评论 - 我会尝试在需要的地方添加解释。

    关于haskell - Map 函数将非函数作为第一个参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29691669/

    相关文章:

    haskell - 使用 WinGHCi 解析预制代码时出现错误

    haskell - 重载一种数据类型还是使用类似的数据类型?

    Haskell 应用程序崩溃 : Segmentation fault/access violation in generated code

    haskell - Data.ByteString 中的 findSubstrings 和 breakSubstring

    haskell - 在 Haskell 中使用二分搜索更快 `elem`

    haskell - Haskell 中的等号 (=) 与左箭头 (<-) 符号

    haskell - 如何从属于产品 monad 的状态 monad 获取 `get` 当前状态?

    java - 为什么 Haskell 中的阶乘计算比 Java 中的快得多

    haskell - 是否可以使用 GHC 泛型重新实现 `Enum` 派生

    haskell - 如何向 http-client-tls 提供客户端证书?