Ошибка «неисчерпывающие шаблоны в функции» при объявлении функции внутри ghci [duplicate]

javax.el.PropertyNotFoundException: свойство 'foo' не найдено в типе com.example.Bean

blockquote>

Это буквально означает, что упомянутый класс com.example.Bean не имеет общедоступный (нестатический!) метод getter для указанного свойства foo. Обратите внимание, что само поле здесь не имеет значения!

Имя открытого метода getter должно начинаться с get, за которым следует имя свойства, которое имеет заглавные буквы только в первой букве имени свойства, как в Foo .

public Foo getFoo() {
    return foo;
}

Таким образом, вам необходимо убедиться, что существует метод получения, точно соответствующий имени свойства, и что метод public (не static) и что метод не принимать любые аргументы и возвращать не void. Если у вас есть один, и он по-прежнему не работает, то есть вероятность, что вы были заняты редактированием кода вперед и назад без прочной очистки сборки, восстановления кода и повторного развертывания / перезапуска приложения. Вы должны убедиться, что вы это сделали.

Для свойств boolean (не Boolean!) Имя метода getter должно начинаться с is вместо get.

public boolean isFoo() {
    return foo;
}

Независимо от типа, наличие самого поля foo, таким образом, не имеет значения. Он может иметь другое имя или быть полностью отсутствующим или даже быть static. Все ниже должно быть доступно ${bean.foo}.

public Foo getFoo() {
    return bar;
}

public Foo getFoo() {
    return new Foo("foo");
}

public Foo getFoo() {
    return FOO_CONSTANT;
}

Понимаете, это не то, что подсчет, но сам метод геттера. Обратите внимание, что само имя свойства не должно быть капитализировано в EL. Другими словами, ${bean.Foo} никогда не будет работать, это должно быть ${bean.foo}.

См. Также:

134
задан Peter McG 17 May 2010 в 01:16
поделиться

5 ответов

для охранников (например, ваш пример), вы можете просто поместить их все на одну строку, и он работает (охранники не заботятся о расстоянии)

let abs n | n >= 0 = n | otherwise = -n

, если вы хотите написать свою функцию с несколькими определения, которые соответствуют шаблону таким аргументам:

fact 0 = 1
fact n = n * fact (n-1)

, тогда вы должны использовать фигурные скобки с точками с запятой, разделяющими определения

let { fact 0 = 1 ; fact n = n * fact (n-1) }
113
ответ дан newacct 19 August 2018 в 14:45
поделиться

Если вы не хотите обновлять GHC только для :{ и :}, вам нужно будет написать все это на одной строке:

> let abs' n | n >= 0 = n | otherwise = -n

Я не знаю любое одно определение в Haskell, которое должно быть записано на нескольких строках. Вышеизложенное действительно работает в GHCi:

> :t abs'
abs' :: (Num a, Ord a) => a -> a

Для других выражений, таких как do блоков, вам нужно будет использовать синтаксис не-макета с фигурными скобками и точками с запятой (eugh).

7
ответ дан C. A. McCann 19 August 2018 в 14:45
поделиться

Похоже, что :{ и :} - довольно новая функция. Возможно, вам понадобится обновить GHC.

Изменить: подтверждено, см. http://www.haskell.org/ghc/docs/6.8.2/html/users_guide/release-6-8- 2.html

16
ответ дан Dan 19 August 2018 в 14:45
поделиться

Дэн прав, но :{ и :} должны появляться в отдельной строке:

> :{ 
> let foo a b = a +
>           b
> :}
> :t foo
foo :: (Num a) => a -> a -> a

Это также взаимодействует с правилом макета, поэтому при использовании do-notation это может быть проще использовать фигурные скобки и полуколоны. Например, это определение не выполняется:

> :{
| let prRev = do
|   inp <- getLine
|   putStrLn $ reverse inp
| :}
<interactive>:1:18:
    The last statement in a 'do' construct must be an expression

Но он работает, когда добавляются фигурные скобки и полуколоны:

> :{
| let prRev = do {
|   inp <- getLine;
|   putStrLn $ reverse inp;
| }
| :}
> :t prRev
prRev :: IO ()

Это будет иметь значение только при вставке определений из файла , где отступы могут меняться.

47
ответ дан Justin Bailey 19 August 2018 в 14:45
поделиться
  • 1
    Это не работает, если у вас есть строка, заканчивающаяся на '=' (с определением, следующим на следующей строке), по крайней мере, в версии 7.6.3. – AdamC 22 May 2014 в 15:15
  • 2
    Возможно, это не удается, потому что вторая и третья строки let не достаточно отступы ...? (Еще два пробела). – Evi1M4chine 8 May 2016 в 02:44

Теперь GHCi имеет режим многострочного ввода, включаемый с помощью: set + m. Например,

Prelude> :set +m
Prelude> let fac 0 = 1
Prelude|     fac n = n * fac (n-1)
Prelude|
Prelude> fac 10
3628800
206
ответ дан Mark Reed 19 August 2018 в 14:45
поделиться
  • 1
    Установка многострочного режима делает ghci очень похожим на интерпретатор Python в этом отношении. Очень удобно! Фактически вы создаете файл .ghci в своем домашнем каталоге, в который вы помещаете :set +m, а многострочный режим становится стандартным при каждом запуске ghci! – kqr 5 November 2013 в 23:04
  • 2
    Это действительно потрясающе. Но я заметил, что когда я устанавливаю свое приглашение с помощью :set prompt "λ ", продолженные строки говорят Prelude вместо λ. Любой способ обойти это? – abhillman 18 June 2014 в 07:02
  • 3
    См. Здесь для патча, чтобы определить новое приглашение продолжения ghc.haskell.org/trac/ghc/ticket/7509#no1 – karakfa 18 June 2014 в 14:22
  • 4
    Чтобы предотвратить появление прелюдии на линиях продолжения, добавьте также: set prompt2 & quot; | & Quot; в вашем .ghci. – Nick 11 September 2016 в 21:10
  • 5
    Вы можете полностью избегать отступов, используя трейлинг let. Просто введите let, а затем новую строку: let ⏎. Тогда fac 0 = 1 ⏎. Тогда fac n = n * fac (n-1) ⏎ ⏎, и все готово! – Iceland_jack 17 September 2016 в 19:34
Другие вопросы по тегам:

Похожие вопросы: