繁体   English   中英

在haskell中对复合函数与map感到困惑

[英]confused about composite function with map in haskell

 let f = map tail.lines
 f "fsdaf\nfdsf\n"

为什么有效?

let f = map tail.tail.lines
f "fasdf\nfasdfdsfd\n"

我得到结果:

["asdfdsfd"]
let f = map (tail.tail).lines
f "fasdf\nfasdfdsfd\n"

我得到结果:

["sdf","sdfdsfd"]

我想知道haskell如何解析上面的代码。

让我们看一下您的第一个示例:

let f = map tail.tail.lines
f "fasdf\nfasdfdsfd\n"

首先, lines断裂的输入字符串转换成一个字符串数组: ["fasdf","fasdfdsfd"]

现在,从右到左工作, tail放下列表的“头”: ["fasdfdsfd"]

最后, map tail将“ tail”应用于列表中的每个元素: ["asdfdsfd"]

您的第二个示例的工作原理类似:

let f = map (tail.tail).lines
f "fasdf\nfasdfdsfd\n"

同样,将输入字符串分成字符串数组: ["fasdf","fasdfdsfd"]

但是,现在您要创建一个复合函数(tail.tail) (两次删除列表的“ head”),然后将其映射到列表中的每个元素。

因此,您将删除每个字符串的前两个字符。

["sdf","sdfdsfd"]

您的两个示例均按预期工作。 阅读haskell中的关联性和复合函数以了解更多信息。

编辑:区别本质上是这样的:

map tail (tail lines)map (tail.tail) lines

请记住,在Haskell中,函数是一等公民-您可以创建复合函数(例如: (+1).(+1) )并执行其他语言中不常见的其他操作(例如, map函数map到列表) 。

第一篇文章是完全正确的,但是由于您希望提出更多问题,所以这是我的尝试...

当您尝试了解此代码的作用时,重要的是要了解这些功能的作用以及应用顺序,因此让我们看一下:

lines :: String -> [String] --takes a String and returns a list of Strings
tail :: [a] -> [a] --takes a (nonempty) list and drops the head (a list containing the rest)
(.) :: (b -> c) -> (a -> b) -> a -> c --function composition

现在这很重要...函数组成是正确的关联,并且优先级为9(最高!)

map :: (a -> b) -> [a] -> [b] --applies (a -> b) to every element of [a]

现在到您的代码:

let f = map tail.tail.lines

相当于

let f x = map tail ((tail.lines) $ x)

这意味着您将把tail映射到lines结果的tail上。 此行为是因为(.)以及函数应用程序在Haskell中是正确的关联。 这也是值得注意的,即(tail.lines)是局部的功能应用的结果(因为你可以的类型(签名见。)的a缺失......为此它会返回一个函数,它的a并返回一个c

在后面的示例中:

let f = map (tail.tail).lines

应用程序的顺序由括号更改...此版本等效于:

let f x = map (tail.tail) (lines $ x)

所以将映射tail.tail以上的结果(滴加头两次) lines

关键是要了解关联性。 它确定在没有括号的情况下优先使用哪个函数,以及这些函数的优先级是否相同。

我希望这可以帮助您了解差异。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM