做你想做的事在 Haskell 中很常见,它有自己的语法,但作为 Haskell,它非常轻量级。例如,这有效:
space :: Char -> [Char]
space = (:" ")
所以你距离正确的解决方案并不遥远。 ([Char]
是相同的String
. " "
是包含该字符的字符串' '
.) 让我们先看看如何使用类似的函数来掌握它的窍门。库中有一个函数叫做equalFilePath :: FilePath -> FilePath -> Bool
,用于测试两个文件名或文件夹名称是否表示相同的内容。 (这解决了在unix上的问题,mydir
不等于MyDir
,但在 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"
, then filter
会尝试使用equalFilePath
没有"MyBestFile.txt"
,因为函数首先吞噬它们的第一个参数。any :: (a -> Bool) -> [a] -> Bool
现在有些函数是中缀运算符 - 从之前和之后获取参数,例如==
or <
。在 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 = (:" ")
希望现在对您来说更有意义。