Error parse error in pattern

Common Misunderstandings Contents Common Mistakes and Incorrect Beliefs By Haskell Beginners People going from zero to Haskell are likely to gain a misunderstanding or miss a point that isn’t stressed enough. Here are some mistakes that have been observed from multiple sources. Indentation Perhaps the first trip-up — you might understand that indentation defines […]

Содержание

  1. Common Misunderstandings
  2. Contents
  3. Common Mistakes and Incorrect Beliefs By Haskell Beginners
  4. Indentation
  5. If / Then / Else
  6. Binding of Type Signatures
  7. do Notation
  8. Iterating Over a List
  9. Guards
  10. Parentheses

Common Misunderstandings

Contents

Common Mistakes and Incorrect Beliefs By Haskell Beginners

People going from zero to Haskell are likely to gain a misunderstanding or miss a point that isn’t stressed enough. Here are some mistakes that have been observed from multiple sources.

Indentation

Perhaps the first trip-up — you might understand that indentation defines where a code block starts and the lack of an equal amount of indentation indicates the previous code block ended. What some miss is that then and else , if used within a section of code where indentation matters, must be indented deeper than the if statement. That is, the position of the «else» in the following is a syntax error:

The following is correct:

Or they can be on the same line as the if:

Fortunately this misfeature is fixed in Haskell 2010, and the first snippet is valid in compilers that support it (e.g. GHC 7.0.1 and later).

If / Then / Else

if-then statements must always include an ‘else’ portion. It might be best not to think of if-then-else as flow control, as in most imperative languages, but think of it as construction of a value using a well formed expression.

The above is valid C code, a ternary operation, that’s used quite commonly as a shortcut to typing out a full if-then-else block. It states that if b is true then x = y otherwise x = z . Notice how this makes no sense without z . Similarly, in Haskell an if / then makes no sense without an else .

What is x when b is false? One should also recognize that the types returned by the then and else branches must match due to Haskell’s strong and static type system.

When if is used for sequencing IO it is not uncommon to see an else that returns a null value:

Such uses can be more succinct if they use the when function (from the Control.Monad module):

Binding of Type Signatures

Due to the typeclass overloading of numbers, lists of numbers are often typed as:

This works fine when the list stands alone, but when applying a function take note the function application binds stronger than the type signature. This means the below signature is invalid:

and should instead be:

or alternatively put the type signature on one of the elements:

do Notation

If the do notation page ever exists I’ll advise you to check it out. Until then, understand that a missing do from the top of a function or code block can result in your compiler giving an error message citing a much later line number. Also, any new blocks (ex: from an if or case ) must have their own do , even if the higher level code block already had one.

Sorry this isn’t the full picture — for an inverse point of view see do notation considered harmful.

Iterating Over a List

Some beginners confuse a single-element list pattern (such as [ x ] ) with a pattern that iterates over every element in the list.

One example that recently (in April, 2008) appeared on the Haskell-Cafe mailing list (see the reply post Re: Embedding newlines into a string?) was the following. Here, one coder attempted to write a function hanoi to solve the Towers of Hanoi problem, but to code it so that each tower could be named polymorphically, using, for example, either Chars or Ints. The problematic code segment was the following:

in the following program:

The coder tried to run the code in WinHugs as follows:

However, this was the result:

The problem was that the parameter [( a , b )] to hanoi_shower only matched the first element of the list, but didn’t iterate over the list as intended.

Here is a corrected version of the code above:

Here, moves is pattern-matched to type [( a , a )] (a list of pairs). The problem is how to iterate over the elements (pairs) of the list while separating the first a of each pair from the second a .

The solution above uses list comprehension: The generator ( a , b ) moves feeds each pair in turn to the left-hand expression ( a , b ) , and this pair is mapped to the left expression, «Move » ++ show a ++ » to » ++ show b ++ «.» , building a new list of sentences representing moves. Then, the function unlines breaks this list into a sequence of lines.

Here is the result of executing the above code in WinHugs:

Notice that since a and b in ( a , b ) are polymorphic types, they can range over both Chars and Ints .

Another way of writing hanoi_shower , using map , is as follows:

Here, move is mapped over moves , and each pair ( a , b ) of moves is pattern-matched against «Move » ++ show a ++ » to » ++ show b ++ «.»

Another way to map over a list is to use recursion, although this method is considered non-idiomatic Haskell (Haskellers generally prefer using higher-order functions over recursion when possible):

Here, in hanoi_shower , the base case is simply an empty list [] . At each recursive step, a list of type [( a , a )] (a list of pairs) is mapped against the parameter ( a , b ) : moves of hanoi_shower . This separates the head of the list ( a , b ) from the tail of the list moves , which then is further matched against (( a , b ) : moves ) on the next recursive call.

There are other ways of iterating over lists as well. One advantage of Haskell is that there are often many ways of performing the same action, including iterating over lists.

Guards

(The following two tips on guards were contributed by the user 7stud in the thread «Top beginner mistakes» (see https://web.archive.org/web/20180127010825/http://article.gmane.org:80/gmane.comp.lang.haskell.beginners/1121) on the Haskell-Beginners mailing list on Wed, 4 Mar 2009 21:54:05 +0000 (UTC).)

Some beginners make the mistake of putting an equals sign after a function name when using guards; viz.:

This causes a cryptic error message similar to the following to be displayed:

dhask . hs : 2 : 4 : parse error on input ` | ‘ Failed , modules loaded : none .

Another common mistake that some beginners make is writing «if» in front of the guard conditions; viz.:

This causes a mysterious error message similar to the following to be shown:

dhask . hs : 2 : 25 : parse error on input ` = ‘ Failed , modules loaded : none .

In both cases, the error messages don’t help to identify the problem.

Parentheses

(The following tip on parentheses was contributed by the user 7stud in the thread «Top beginner mistakes» (see https://web.archive.org/web/20180127010825/http://article.gmane.org:80/gmane.comp.lang.haskell.beginners/1121) on the Haskell-Beginners mailing list on Wed, 4 Mar 2009 21:54:05 +0000 (UTC).)

Some beginners make the mistake of not putting parentheses around arguments of the form x:xs; viz.:

This causes an ambiguous error message similar to the following to be shown:

dhask . hs : 1 : 0 : Parse error in pattern Failed , modules loaded : none .

Here, the error message doesn’t help to recognize the problem.

Источник

Recommend Projects

  • React photo

    React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo

    Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo

    Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo

    TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo

    Django

    The Web framework for perfectionists with deadlines.

  • Laravel photo

    Laravel

    A PHP framework for web artisans

  • D3 photo

    D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Visualization

    Some thing interesting about visualization, use data art

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo

    Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo

    Microsoft

    Open source projects and samples from Microsoft.

  • Google photo

    Google

    Google ❤️ Open Source for everyone.

  • Alibaba photo

    Alibaba

    Alibaba Open Source for everyone

  • D3 photo

    D3

    Data-Driven Documents codes.

  • Tencent photo

    Tencent

    China tencent open source team.

isValid :: Position -> Bool
isValid Position(x _) = x
isValid Position(_ y) = y
    | x 'elem' ['a'..'h'] && y 'elem' [1..8] = True
    | otherwise = False

Я продолжаю получать эту ошибку error: Parse error in pattern: x Я пытаюсь написать функцию, которая сообщает мне, является ли данная позиция действительной или нет. Где x['a'..'h'], а y[1..8]

3 ответа

Лучший ответ

В

    | x 'elem' ['a'..'h'] && y 'elem' [1..8] = True

x не связан. Это вообще не появляется в

isValid Position(_ y) = y

В частности. Кроме того, вы, вероятно, хотели использовать `elem`, а не 'elem'.

Я пытаюсь написать функцию, которая сообщает мне, является ли данная позиция действительной или нет. Где х [[a ‘..’ h ‘] и у [1..8]

Вы не написали определение Position, но похоже, что это будет что-то вроде

data Position = Position Int Int                                                                                                                                     

isValid :: Position -> Bool
isValid (Position x y) = x `elem` ['a'..'h'] && y `elem` [1..8]

(который строит для меня).


2

Antal Spector-Zabusky
1 Июн 2017 в 08:41

Я получаю эту ошибку: Ошибка разбора в шаблоне: x Я пытаюсь написать функцию, которая сообщает мне, является ли данная позиция действительной или нет. Где x['a'..'h'], а y[1..8].

Другие ответы уже обсуждали, что не так: вы использовали охрану в предложении, где нет границ x:

isValid Position(_ y) = y

И, кроме того, вы используете кавычки вместо обратных кавычек с функцией elem:

x 'elem' ['a'..'h']

Таким образом, строгое решение будет:

isValid :: Position -> Bool
isValid (Position x y)
    | x `elem` ['a'..'h'] && y `elem` [1..8] = True
    | otherwise = False

Поскольку мы на самом деле возвращаем результат охраны, нам не нужно использовать охрану, и мы можем свернуть охрану в одно выражение:

isValid :: Position -> Bool
isValid (Position x y) = x `elem` ['a'..'h'] && y `elem` [1..8]

Тем не менее, поскольку мы здесь работаем с range , а второй диапазон является целым числом, нам не нужно использовать elem для диапазона, мы можем использовать:

isValid :: Position -> Bool
isValid (Position x y) = 'a' <= x && x <= 'h' && 1 <= y && y <= 8

Для таких небольших диапазонов, вероятно, не будет большого влияния на производительность, но elem работает в O (n) в худшем случае, тогда как две проверки границ работают в O ( 1 ) .


3

Willem Van Onsem
1 Июн 2017 в 22:51

Как объясняется здесь: Синтаксическая ошибка в ‘mod’ Haskell

Синтаксис для использования именованной функции в качестве инфиксного оператора использует обратные метки (серьезные акценты, U + 0060), а не апострофы:

    | x `elem` ['a'..'h'] && y `elem` [1..8] = True
        ------                 ------
    | otherwise = False

Кроме того, Position(x _) и Position(_ y) не являются допустимыми шаблонами — вы, вероятно, намеревались использовать (Position x _) и (Position x y). Обратите внимание на x, поскольку x не входит в область действия в уравнении, которое вы написали для (Position _ y).

(Position x _) будет соответствовать всем позициям, поэтому я подозреваю, что вы намеревались:

isValid :: Position -> Bool
isValid (Position x y)
    | x `elem` ['a'..'h'] && y `elem` [1..8] = True
    | otherwise = False

Или проще:

isValid :: Position -> Bool
isValid (Position x y) = x `elem` ['a'..'h'] && y `elem` [1..8]


3

Jon Purdy
1 Июн 2017 в 05:37

Понравилась статья? Поделить с друзьями:
  • Error pixel and vertex shaders not found
  • Error pipeline could not be constructed no element v4l2src
  • Error pam authentication error for illegal user
  • Error pipe listening
  • Error pages flask