运营商的部分应用

时间:2012-09-23 01:11:34

标签: function haskell types currying partial-application

如果我想在字符末尾添加一个空格来返回一个列表,如果我没有传递任何参数,我将如何使用部分应用程序完成此操作?

类型也是吗?

space :: Char -> [Char]

由于使用++和:运算符“解析错误”,我在最后添加空格时遇到了麻烦。

到目前为止我所拥有的是:

space :: Char -> [Char]
space = ++ ' '

任何帮助将不胜感激!感谢

2 个答案:

答案 0 :(得分:5)

在Haskell中做你想要的东西是如此常见,它有自己的语法,但作为Haskell,它非常轻巧。例如,这有效:

space :: Char -> [Char]
space = (:" ")

所以你离正确的解决方案不远了。 ([Char]String相同。" "是包含字符' '的字符串。)让我们先看看使用类似的函数来获取它。在名为equalFilePath :: FilePath -> FilePath -> Bool的库中有一个函数,用于测试两个文件名或文件夹名称是否代表相同的东西。 (这解决了在unix上mydirMyDir不同的问题,但在Windows上它是。)也许我想检查列表以查看它是否有我想要的文件:

isMyBestFile :: FilePath -> Bool
isMyBestFile fp = equalFilePath "MyBestFile.txt" fp

但是因为函数首先吞噬它们的第一个参数,然后返回一个新函数来吞噬下一个,等等,我可以写得更短

isMyBestFile = equalFilePath "MyBestFile.txt"

这是有效的,因为equalFilePath "MyBestFile.txt"本身就是一个带有一个参数的函数:它的类型是FilePath -> Bool。这是部分应用,它非常有用。也许我不想打扰单独的isMyBestFile函数,但想检查我的列表中是否有任何函数:

hasMyBestFile :: [FilePath] -> Bool
hasMyBestFile fps = any (equalFilePath "MyBestFile.txt") fps

或者只是部分应用的版本:

hasMyBestFile = any (equalFilePath "MyBestFile.txt") 

请注意我需要将括号放在equalFilePath "MyBestFile.txt"周围,因为如果我写了any equalFilePath "MyBestFile.txt",那么filter会尝试仅使用equalFilePath而不使用"MyBestFile.txt"因为函数首先吞噬了他们的第一个参数。 any :: (a -> Bool) -> [a] -> Bool

现在有些函数是中缀运算符 - 从==<之前和之后获取它们的参数。在Haskell中,这些只是常规函数,而不是硬编码到编译器中(但是指定了优先级和关联性规则)。如果我是unix用户,从未听说过equalFilePath并且不关心它解决的可移植性问题,那么我可能会想做什么

hasMyBestFile = any ("MyBestFile.txt" ==)

它会工作,只是相同,因为==是一个常规函数。当您使用运算符函数执行此操作时,它称为运算符部分。

它可以在前面或后面工作:

hasMyBestFile = any (== "MyBestFile.txt")

您可以使用您喜欢的任何操作员:

hassmalls = any (< 5)

和列表的便捷运算符是::会在左侧显示一个元素,在右侧显示一个列表,然后将两者放在一个新的列表中,因此'Y':"es"会为您提供"Yes"。 (秘密地,"Yes"实际上只是'Y':'e':'s':[]的简写,因为:是构造函数/元素组合值,但这里没有相关性。)使用:我们可以定义

space c = c:" "

我们可以像往常一样摆脱c

space = (:" ")
希望现在对你更有意义。

答案 1 :(得分:4)

你想要的是operator section。为此,您需要用括号括起应用程序,即

space = (: " ")

的语法糖
space = (\x -> x : " ")

(++)在这里不起作用,因为它需要一个字符串作为第一个参数,比较:

(:)  :: a -> [a] -> [a]
(++) :: [a] -> [a] -> [a]