Haskell中无点功能的先决条件是什么 [英] What are the prerequisites for a point-free function in Haskell
问题描述
我一直认为,无点函数的前提条件是使函数参数到达定义的末尾.例如
I always thought that the prerequisites for a pointfree function were to get the function arguments to the end of the definition. E.g.
-- This can be made pointfree quite easily:
let lengths x = map length x
let lengths' = map length
-- However this cannot:
let lengthz x = length `map` x
-- let lengthz' = length `map` (parse error)
I originally came across this reading this question. There we have this example:
agreeLen :: (Eq a) => [a] -> [a] -> Int
agreeLen x y = length $ takeWhile id $ zipWith (==) x y
-- This may look like it can easily be made pointfree, however it cannot
-- agreeLen' :: (Eq a) => [a] -> [a] -> Int
-- agreeLen' = length $ takeWhile id $ zipWith (==) (zipWith is applied to too few arguments)
那么为什么我的第一个示例可以变得没有意义,而其他两个却不能?
So why can my first example be made pointfree, but the other two cannot?
推荐答案
-- However this cannot:
let lengthz x = length `map` x
-- let lengthz' = length `map` (parse error)
\ x->长度`map` x
的免费点简直就是 map length
.中缀反引号只是语法糖.(正如chepner指出的,如果您确实想要它,则可以使用一个部分,即(长度为"map"的长度)
.)
\x -> length `map` x
written point free is simply map length
. The infix backticks are just syntactical sugar. (As chepner points out, if you really want it you can use a section, i.e. (length `map`)
.)
agreeLen :: (Eq a) => [a] -> [a] -> Int
agreeLen x y = length $ takeWhile id $ zipWith (==) x y
-- This may look like it can easily be made pointfree, however it cannot
这里的关键词是轻松".如果您足够努力,几乎所有东西都可以变得毫无意义.在这种情况下,如果我们用(.)
而不是($)
:
The key word here is "easily". Pretty much anything can be made point-free if you try hard enough. In this case, omitting the y
parameter is easy if we write agreeLen
in terms of (.)
rather than ($)
:
agreeLen x y = (length . takeWhile id . zipWith (==) x) y
agreeLen x = length . takeWhile id . zipWith (==) x
对于 x
,我们可以通过使用(.)
将 zipWith(==)x
与其他功能只是使用功能修改值的另一种情况:
As for x
, we can handle it by treating the use of (.)
to compose zipWith (==) x
with the other functions as just another case of a value being modified with a function:
agreeLen x = (.) (length . takeWhile id) (zipWith (==) x)
agreeLen x = ((length . takeWhile id) .) (zipWith (==) x) -- cosmetical change
agreeLen x = (((length . takeWhile id) .) . zipWith (==)) x
agreeLen = ((length . takeWhile id) .) . zipWith (==)
这不是您实际上在实践中想要做的事情,但是肯定有可能.
It is not something you'd actually want to do in practice, but it is certainly possible.
这篇关于Haskell中无点功能的先决条件是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!