在Haskell编程的第一性原则书中,有一个练习告诉我们编写一个函数,其中包含一个带空格的字符串,将它除以空格,然后将非空间块加载到字符串列表中。我的第一次尝试是:
splitString :: String -> [String]
splitString str
| str == "" = []
| otherwise = takeWhile (/=' ') str : splitString $ drop 1 $ dropWhile (/=' ') str现在这不编译了。如果我用相应的括号替换第一个($) (splitString之后),如下所示:
takeWhile (/=' ') str : splitString (drop 1 $ dropWhile (/=' ') str)那就成功了。根据我到目前为止所了解到的($),这两者不应该是等价的吗?($)是正确的联想,所以在我看来应该发生的事情是
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我可以从“($)的第一个论点”中看出这是在谈论splitString,但我对这句话的意思感到困惑。
but its type `[[Char]]` has none应该意味着。
发布于 2016-09-11 03:56:25
如果添加parens,代码将工作,如下所示:
...
| otherwise = takeWhile (/=' ') str : ( splitString $ drop 1 $ dropWhile (/=' ') str )
-- ^^^ ^^^ 否则,Haskell会将Otherwise子句解释为:
( takeWhile (/=' ') str : splitString )
$ drop 1
$ dropWhile (/= ' ') str更新
你在评论中提到的版本:
takeWhile (/= ' ') str : splitString ( ... )
-- \__ a __/ \_ b _/ c : \___ d ___/ \_ e _/具有a b c : d e形式,Haskell总是将其解释为(a b c) : (d e),因为:是唯一出现表达式的infix操作符。
当你有这样的事情时:
a b c : d e $ f $ g您必须考虑到:和$ infix运算符的相对优先级。由于$是infixr 0,所以它不像:那样紧密绑定,因此可以得到以下正确的关联分组:
(a b c : d e) $ (f $ g)https://stackoverflow.com/questions/39432649
复制相似问题