在Haskell Programming from First Principles一书中,有一个练习告诉我们编写一个函数,它接受一个带有空格的字符串,用空格分割它,并将非空间块加载到一个字符串列表中.我的第一次尝试是:
splitString :: String -> [String]
splitString str
| str == "" = []
| otherwise = takeWhile (/=' ') str : splitString $ drop 1 $ dropWhile (/=' ') str
Run Code Online (Sandbox Code Playgroud)
现在这不编译.如果我将第一个($)(右后splitString)替换为相应的括号对,如下所示:
takeWhile (/=' ') str : splitString (drop 1 $ dropWhile (/=' ') str)
Run Code Online (Sandbox Code Playgroud)
然后它工作.根据我迄今为止所学到的关于($)的内容,不应该两者相等吗?($)是正确的联想,因此在我看来应该发生的事情是什么
dropWhile (/=' ') str 首先评估drop 1 (dropWhile (/=' ') str) 是下一个splitString.相反,我得到一个错误,从ghc它说
Couldn't match expected type ‘[Char] -> [String]’
with actual type ‘[[Char]]’
The first argument of ($) takes one argument,
but its type ‘[[Char]]’ has none
Run Code Online (Sandbox Code Playgroud)
我可以通过"($)的第一个论点"看到它splitString,但我对这个陈述感到困惑
but its type `[[Char]]` has none
Run Code Online (Sandbox Code Playgroud)
应该是的意思.
如果您添加如下所示的parens,您的代码将起作用:
...
| otherwise = takeWhile (/=' ') str : ( splitString $ drop 1 $ dropWhile (/=' ') str )
-- ^^^ ^^^
Run Code Online (Sandbox Code Playgroud)
否则Haskell将else子句解释为:
( takeWhile (/=' ') str : splitString )
$ drop 1
$ dropWhile (/= ' ') str
Run Code Online (Sandbox Code Playgroud)
更新
您在评论中提到的版本:
takeWhile (/= ' ') str : splitString ( ... )
-- \__ a __/ \_ b _/ c : \___ d ___/ \_ e _/
Run Code Online (Sandbox Code Playgroud)
具有a b c : d eHaskell总是解释的形式,(a b c) : (d e)因为:它是唯一出现表达式的中缀运算符.
当你有类似的东西:
a b c : d e $ f $ g
Run Code Online (Sandbox Code Playgroud)
你必须考虑:和中$缀运算符的相对优先级.既然$被定义为infixr 0,它不会像以前那样紧密绑定,:并且您获得以下右关联分组:
(a b c : d e) $ (f $ g)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |