0

I'm trying to do the following in Haskell:

 someFunction :: [] -> Int
 someFunction list 
 let a
 | length list == 1 = 10
 | otherwise = 0
 b
 | length list == 1 = 10 
 | otherwise = 0
 in findValues (a+b)

So that the values of a and b will be dependent on the conditions in the guards being met or not. This syntax keeps giving me errors and I'm not sure why. Do I need to use a where clause or is there a correct "let" syntax to achieve what I want?

Thanks for any help

Chris Stryczynski
  • 30,145
  • 48
  • 175
  • 286
Tom coates
  • 53
  • 1
  • 7

2 Answers2

9

This is doable, but keep in mind that length list == 1 is very inefficient: it will scan all the entries to count them one by one, spending O(N) time, to compare with 1.

Instead, consider using a case .. of which can check that in constant time.

someFunction :: [] -> Int
someFunction list = let
   a = case list of
       [_] -> 10   -- list is of the form [x] for some x
       _   -> 0    -- list is of any other form
   b = case list of
       [_] -> 10
       _   -> 0
   in findValues (a+b)

or even:

someFunction :: [] -> Int
someFunction list = let
   (a,b) = case list of
       [_] -> (10,10)    -- list is of the form [x] for some x
       _   -> (0 ,0 )    -- list is of any other form
   in findValues (a+b)

(Also note that a and b have the same value: is that intentional, or is the code only an example?)

When possible I'd strongly recommend to avoid guards in favor of pattern matching.

chi
  • 111,837
  • 3
  • 133
  • 218
6

It's a bit hard to say, but I'm guessing you meant

someFunction :: [] -> Int
someFunction list =
  let a | length list == 1 = 10
        | otherwise = 0
      b | length list == 1 = 10 
        | otherwise = 0
  in findValues (a+b)
dfeuer
  • 48,079
  • 5
  • 63
  • 167