簡體   English   中英

Haskell $運算符:為什么不起作用?

[英]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)

然后就可以了。 但是,根據我到目前為止所學到的($),兩者不應該等效嗎? ($)是正確的關聯,所以在我看來應該發生的是

  1. dropWhile (/=' ') str評估dropWhile (/=' ') str
  2. 接下來是drop 1 (dropWhile (/=' ') str)
  3. 然后將結果傳遞到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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM