Шаблон Haskell не установлен ... тогда он есть - PullRequest
1 голос
/ 15 апреля 2020

Я пишу программу на Haskell, и в ней много скобок. Поэтому, чтобы устранить этот ужасный беспорядок, я пару раз использую оператор $, чтобы его было легче читать. Например:

longFunc arg1 (anotherFunc (yetAnotherFunc arg2))

заменяется на

longFunc arg1 $ anotherFunc $ yetAnotherFunc arg2

Но когда я компилирую свою программу с использованием GHCi, я получаю сообщение:

MyFile.hs:18:18: error:
    parse error on input ‘$’
    Perhaps you intended to use TemplateHaskell
Failed, modules loaded: none.

Вот строки 16 -18:

isDigit :: Char -> Bool
isDigit c =
  c `elem` $ ['0'..'9'] ++ "."

Я был сбит с толку, потому что я использовал оператор $ несколько раз (с одним и тем же компилятором) следующим образом:

main = putStrLn $ show 42

Поэтому я набрал этот код в мой файл в качестве теста удалил другие $ вхождения и загрузил его.

И это сработало!

Может кто-нибудь сказать, пожалуйста, что происходит?

1 Ответ

7 голосов
/ 15 апреля 2020

Вы не можете использовать ($) сразу после другого инфиксного оператора. Строка 18:

c `elem` $ ['0'..'9'] ++ "."

необходимо переписать как одну из следующих опций:

  1. Оставьте скобки как оригинальные:

    c `elem` (['0'..'9'] ++ "."])
    
  2. Применить ($) к фрагменту elem:

    (c `elem`) $ ['0'..'9'] ++ "."
    
  3. Преобразовать вызов в elem в префиксный вызов:

    elem c $ ['0'..'9'] ++ "."
    

Я рекомендую вариант 3. Последовательные инфиксные операторы (в данном случае `elem` и $) не имеют четко определенного приоритета и приводят в замешательство синтаксический анализатор. Общее правило заключается в том, что инфиксный оператор всегда должен иметь полное выражение на каждой стороне. c `elem` не является полным выражением, поэтому оно не допускается слева от $. Точно так же $ ['0'..'9'] ++ "." не является полным выражением, поэтому он не может быть правой стороной `elem`.

...