Andriy Drozdyuk
Andriy Drozdyuk

Reputation: 61091

Parse error on pattern

Trying to implement a function that will return a list of ints the represent an ordering of each list of doubles, e.g.:

orderings [ [1.0, 2.0, 3.0], [3.0, 2.0, 1.0] ]
> [ [0, 1, 2], [2, 1, 0] ]

However, having trouble with my pattern matching for some reason:

import Data.List

-- Return a list of orderings for each list of doubles
orderings:: [[Double]] -> [Int]
orderings [] = []
orderings x:xs = (ordering x):(orderings xs)

ordering:: [Double] -> [Int]
ordering xs = [i | (i, _) <- sorted] where
    sorted = sortBy (\(i1, e1) (i2,e2) -> compare e1 e2) $ zip [0..] xs

Error is:

Parse error in pattern: orderings

Can't see the error for the life of me!

Upvotes: 1

Views: 873

Answers (4)

pat
pat

Reputation: 12749

The result of orderings should be [[Int]] as pointed out previously. However, the implementation of the functions can be simplified to:

import Data.List

-- Return a list of orderings for each list of doubles
orderings :: [[Double]] -> [[Int]]
orderings = map ordering

ordering :: [Double] -> [Int]
ordering = map snd . sort . flip zip [0..]

Upvotes: 3

Matt Fenwick
Matt Fenwick

Reputation: 49095

Two more problems (in addition to the missing parentheses around x:xs):

  1. the type of orderings is wrong; I suspect it should be [[Double]] -> [[Int]]

  2. x is not in scope in ordering; I suspect it should be xs

Here's the corrected code:

import Data.List

-- Return a list of orderings for each list of doubles
orderings:: [[Double]] -> [[Int]]  -- changed type
orderings [] = []
orderings (x:xs) = (ordering x):(orderings xs)

ordering:: [Double] -> [Int]
ordering xs = [i | (i, _) <- sorted] where
    sorted = sortBy (\(i1, e1) (i2,e2) -> compare e1 e2) $ zip [0..] xs -- xs not x!

Upvotes: 5

Johannes Weiss
Johannes Weiss

Reputation: 54051

There are 3 errors:

In the line orderings x:xs = (ordering x):(orderings xs) you try to cons (:) a list and a list (but cons generates list with the given value prepended) and you forget the parens around the x:xs cons pattern match.

The type of : is:

Prelude> :type (:)
(:) :: a -> [a] -> [a]

The correct form of the line is:

orderings (x:xs) = (ordering x) ++ (orderings xs)

since ++ concats to lists:

Prelude> :type (++)
(++) :: [a] -> [a] -> [a]

The last error is that in the last line, it should be xs instead of x

Upvotes: 0

sth
sth

Reputation: 229633

You have to put parenthesis around the x:xs pattern:

orderings (x:xs) = ...

Upvotes: 2

Related Questions