简体   繁体   中英

How to use let with guards in Haskell?

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

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.

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)

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