简体   繁体   中英

keep getting a parse indendation error in Haskell what am I doing wrong

cube = x*x*x
cube xs = map cube [x | x <-xs] 
           where x mod 2 == 1

so I'm trying to get the odd number of the list

Thank you all for your help!

The above code fragment contains some errors:

  1. you here use where as a filter, but in Haskell a where clause is used to define locally scoped variables;
  2. you only define the (x:xs) pattern, so even if this works, it will error on the empty list;
  3. [x | x <- xs] [x | x <- xs] is just the identity function for a list, so we can omit that, furthermore it is advisable not to name variables the same as the "outer" variables, since that creates confusion; and
  4. x mod 2 == 1 can be replaced by odd :: Integral i => i -> Bool .

We can fix this by writing it like:

cubeOdds2 :: Integral i => [i] -> [i]
cubeOdds2 = map cube . filter odd
    where cube x = x * x * x

For example:

Prelude> cubeOdds2 [1,4,2,5]
[1,125]

We here thus use filter :: (a -> Bool) -> [a] -> [a] to filter the list, such that only odd numbers are retained, and then use map :: (a -> b) -> [a] -> [b] to perform a mapping on these elements with cube as the function that takes an element and returns the mapping for that element.

You have a few problems. One is incorrect syntax the other is misunderstanding what the where clause is for. Then there's pattern matching unnecessarily. Finally, and not strictly a problem, is a mix of list notation and higher order functions.

Not a Where Clause

A where clause is for variable bindings, such as:

where functionName param1 param2 = <some expression>

The clause is not useful for constraints over the variables. For a list-notation style constraint just add a comma and the constraint:

[x | x <- list, predicate1 x, predicate2 x]

Pattern Matching

The function cubeOdds2 (x:xs) will bind x to the first element in the list then xs to the remaining list. It will also fail with an exception on empty lists. What you seem to want is to just operate on the list , so don't pattern match and just use a variable name such as cubeOdds2 xs .

List Comprehension Notation vs Higher Order Functions

A list comprehension is syntax like [a | val <- list, predicate val, let a = someFunction val] [a | val <- list, predicate val, let a = someFunction val] . Higher order functions can do everything the list comprehension does, such as map ping the someFunction computation and filter ing based on the predicate.

Some Solutions

With these changes we have three final forms for your cubeOdds function.

First, your mix of conventions:

cubeOdds3 xs = map cube [x | x <- xs, x `mod` 2 == 1]

Second, just list comprehension:

cubeOdds4 xs = [cube x | x <- xs, x `mod` 2 == 1]

Third, just higher order functions:

cubeOdds5 xs = map cube (filter (\x -> x `mod` 2 == 1) xs)

Code Golf

We can even go further and use the built in odd function:

cubeOdds6 xs = [cube x | x <- xs, odd x]

And use point free style too:

cubeOdds7 = map cube . filter odd

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM