运营商的部分应用 [英] Partial application of operators
问题描述
如果我想在字符末尾添加一个空格来返回一个列表,如果我没有传递任何参数,我将如何用部分应用程序完成此操作?
If I want to add a space at the end of a character to return a list, how would I accomplish this with partial application if I am passing no arguments?
类型也是?
space :: Char -> [Char]
由于解析错误,我在最后添加空格时遇到问题,通过使用++和:操作符。
I'm having trouble adding a space at the end due to a 'parse error' by using the ++ and the : operators.
到目前为止我是:
What I have so far is:
space :: Char -> [Char]
space = ++ ' '
任何帮助将不胜感激!谢谢
Any help would be much appreciated! Thanks
推荐答案
做你想要的东西在Haskell中很常见,它有自己的语法,但作为Haskell,它非常轻巧。例如,这可以工作:
Doing what you want is so common in Haskell it's got its own syntax, but being Haskell, it's extraordinarily lightweight. For example, this works:
space :: Char -> [Char]
space = (:" ")
所以你离我们不远正确的解决方案。 ( [Char]
)与 String 。
是包含字符
''
的字符串。)让我们先看看使用类似的函数来获取它的挂起。库中有一个函数叫做 equalFilePath :: FilePath - > FilePath - > Bool
,它用于测试两个文件名或文件夹名是否代表相同的事情。 (这解决了unix上的问题, mydir
与 MyDir
不一样,但在Windows上是这样的。 )也许我想检查一个列表,看它是否有我想要的文件:
so you weren't far off a correct solution. ([Char]
is the same as String
. " "
is the string containing the character ' '
.) Let's look at using a similar function first to get the hang of it. There's a function in a library called equalFilePath :: FilePath -> FilePath -> Bool
, which is used to test whether two filenames or folder names represent the same thing. (This solves the problem that on unix, mydir
isn't the same as MyDir
, but on Windows it is.) Perhaps I want to check a list to see if it's got the file I want:
isMyBestFile :: FilePath -> Bool
isMyBestFile fp = equalFilePath "MyBestFile.txt" fp
然后返回一个新的函数来吞噬下一个,等等,我可以写得更简短。
but since functions gobble their first argument first, then return a new function to gobble the next, etc, I can write that shorter as
isMyBestFile = equalFilePath "MyBestFile.txt"
这是因为 equalFilePathMyBestFile.txt
本身是一个接受一个参数的函数:它的类型是 FilePath - >布尔
。这是部分应用程序,它非常有用。也许我不想打扰写一个单独的 isMyBestFile
函数,但想检查我的任何列表是否有它:
This works because equalFilePath "MyBestFile.txt"
is itself a function that takes one argument: it's type is FilePath -> Bool
. This is partial application, and it's super-useful. Maybe I don't want to bother writing a seperate isMyBestFile
function, but want to check whether any of my list has it:
hasMyBestFile :: [FilePath] -> Bool
hasMyBestFile fps = any (equalFilePath "MyBestFile.txt") fps
或者只是再次部分应用的版本:
or just the partially applied version again:
hasMyBestFile = any (equalFilePath "MyBestFile.txt")
请注意,我需要在 equalFilePathMyBestFile.txt
中放置括号,因为如果我写任何equalFilePathMyBestFile.txt
,然后 filter
会尝试使用 equalFilePath
没有MyBestFile.txt
,因为函数首先捕获它们的第一个参数。 any ::(a - > Bool) - > [a] - > Bool
Notice how I need to put brackets round equalFilePath "MyBestFile.txt"
, because if I wrote any equalFilePath "MyBestFile.txt"
, then filter
would try and use just equalFilePath
without the "MyBestFile.txt"
, because functions gobble their first argument first. any :: (a -> Bool) -> [a] -> Bool
现在一些函数是infix操作符 - 从前后获取参数,如 ==
或<
。在Haskell中,这些只是常规函数,没有硬编码到编译器中(但指定了优先级和关联性规则)。如果我是一个从来没有听说过 equalFilePath
的unix用户,并且不关心它解决的可移植性问题,那么我可能会想要做到这一点
Now some functions are infix operators - taking their arguments from before and after, like ==
or <
. In Haskell these are just regular functions, not hard-wired into the compiler (but have precedence and associativity rules specified). What if I was a unix user who never heard of equalFilePath
and didn't care about the portability problem it solves, then I would probably want to do
hasMyBestFile = any ("MyBestFile.txt" ==)
,它会工作,只是相同,因为==是一个常规函数。当你用一个操作符函数做这件事时,它被称为一个操作符部分。
and it would work, just the same, because == is a regular function. When you do that with an operator function, it's called an operator section.
它可以在前面或后面工作:
It can work at the front or the back:
hasMyBestFile = any (== "MyBestFile.txt")
,你可以使用任何你喜欢的操作符:
and you can do it with any operator you like:
hassmalls = any (< 5)
以及一个便于操作的列表是:
。 :
在左边的一个元素和右边的一个列表中,依次创建一个新的列表,所以'Y': es
给你是
。 (秘密地,是
实际上只是'Y'的缩写:'e':'s':[]
因为:
是一个构造函数/元素合并值的值,但在这里没有关系。)使用:
我们可以定义
and a handy operator for lists is :
. :
takes an element on the left and a list on the right, making a new list of the two after each other, so 'Y':"es"
gives you "Yes"
. (Secretly, "Yes"
is actually just shorthand for 'Y':'e':'s':[]
because :
is a constructor/elemental-combiner-of-values, but that's not relevant here.) Using :
we can define
space c = c:" "
,我们可以像往常一样摆脱 c
and we can get rid of the c
as usual
space = (:" ")
感觉到你现在。
这篇关于运营商的部分应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!