#haskell #cons
#haskell #cons
Вопрос:
Я новичок в Haskell, и я в основном пытаюсь понять, почему это не удается:
Prelude> test
[2,3,4,1]
Prelude> tail $ tail test
[4,1]
Prelude> 2 : [4,1]
[2,4,1]
Prelude> 2 : tail $ tail test
<interactive>:27:1: error:
• Couldn't match expected type ‘[Integer] -> t’
with actual type ‘[Integer]’
• The first argument of ($) takes one argument,
but its type ‘[Integer]’ has none
In the expression: 2 : tail $ tail test
In an equation for ‘it’: it = 2 : tail $ tail test
• Relevant bindings include it :: t (bound at <interactive>:27:1)
<interactive>:27:5: error:
• Couldn't match expected type ‘[Integer]’
with actual type ‘[a0] -> [a0]’
• Probable cause: ‘tail’ is applied to too few arguments
In the second argument of ‘(:)’, namely ‘tail’
In the expression: 2 : tail
In the expression: 2 : tail $ tail test
Prelude>
Я вижу сообщение об ошибке «Вероятная причина: ‘tail’ применяется к слишком небольшому количеству аргументов», но я недостаточно понимаю, чтобы понять, что его вызывает, потому что это же выражение только что сработало.
Комментарии:
1.
2 : tail $ tail test
эквивалентно(2 : tail) (tail test)
, не2 : (tail (tail test))
2. @WillemVanOnsem: это сработало! Спасибо. Как я упоминал в другом ответе, я попробовал
2 : $ tail $ tail test
, и он вернулсяparse error on input ‘$’
. Знаете ли вы, почему это так?
Ответ №1:
Вам нужно знать о группировке / приоритете операторов: 2 : tail $ tail test
это не то же самое, что «cons 2 на значение tail $ tail test
«, не больше, чем 5 * 3 2
«умножить результат 3 2
на 5″. В обоих случаях вам нужно добавить круглые скобки, если вы хотите выполнить именно эту операцию.
Комментарии:
1. ах! Итак, я действительно попытался:
2 : $ tail $ tail test
и это тоже не удалось. Насколько я понимаю, $ и ввод круглых скобок эквивалентны?2. Помещение круглых скобок действительно работает! Спасибо за ответ. Если бы вы могли также объяснить, почему
$
работает din, это было бы потрясающе!3.
$
не эквивалентно скобкам, но является способом избежать скобок, поскольку$
имеет более низкий приоритет, чем (почти) любой другой оператор.4. @Yathi
2 : $ tail $ tail test
не работает точно по той же причине, которая5 * 3 2
не работает.5. @Yathi, но
(2:) $ tail $ tail test
и(:) 2 $ tail $ tail test
оба будут работать.(:)
является фактической функцией, соответствующей:
оператору, и(2 :)
является либо(:) 2
илиx -> 2 : x
(я не помню, какой, и это очень редко имеет значение).