[英]Haskell $ operator: why doesn't this work?
在《 第一原理的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
評估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
應該是這個意思。
如果您添加如下所示的括號,您的代碼將起作用:
...
| otherwise = takeWhile (/=' ') str : ( splitString $ drop 1 $ dropWhile (/=' ') str )
-- ^^^ ^^^
否則,Haskell會將else子句解釋為:
( takeWhile (/=' ') str : splitString )
$ drop 1
$ dropWhile (/= ' ') str
更新資料
您在評論中提到的版本:
takeWhile (/= ' ') str : splitString ( ... )
-- \__ a __/ \_ b _/ c : \___ d ___/ \_ e _/
格式為abc : de
,Haskell始終將其解釋為(abc) : (de)
因為:
是出現表達式的唯一中綴運算符。
當你有類似的東西:
a b c : d e $ f $ g
您必須考慮:
和$
infix運算符的相對優先級。 由於$
被定義為infixr 0
,它不綁定為緊:
你會得到下面的右關聯分組:
(a b c : d e) $ (f $ g)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.