简体   繁体   中英

How to check that I'm dealing with a list in Haskell?

I'm learning Haskell, and I'm trying to add preconditions to a (trivial, as an exercise) element_at function (code below). I've created a "helper" elem_at_r because otherwise, len x fails at some point (when x is a 'literal' rather than a list? - I still have trouble parsing ghci's error messages). elem_at now has all the error checking, and elem_at_r does the work. In elem_at , I'd like to add a check that x is indeed a list (and not a 'literal'). How can I do that?

len x = sum [ 1 | a <- x]

elem_at_r x n | n == 0     = head x
              | 0 < n      = elem_at_r (tail x) (n-1)

elem_at x n | x == []    = error "Need non-empty list"
            | len x <= n = error "n too large " ++ show (len x)
            | n < 0      = error "Need positive n"
            | otherwise  = elem_at_r x n  

Thanks!

Frank

Due to Haskell's type system, elem_at can only take a list as its first argument ( x ); if you try to pass a non-list, GHC will detect this and give an error at compile time (or interpretation time in GHCi). I don't know why len would "fail"; could you post the error message that GHCi gives you?

It looks like you were getting errors because of the "x == []" line. The code below pattern matches for that condition and adds a few signatures. Otherwise it is the same. Hope it helps.

len x = sum [ 1 | a <- x]

elem_at_r :: [a] -> Int -> a
elem_at_r x n | n == 0     = head x
              | 0 < n      = elem_at_r (tail x) (n-1)

elem_at :: [a] -> Int -> a
elem_at [] _ = error "Need non-empty list"
elem_at x n | len x <= n = error ("n too large " ++ show (len x))
            | n < 0      = error "Need positive n"
            | otherwise  = elem_at_r x n 

You could also make your helper functions part of this function using a where clause:

elem_at :: [a] -> Int -> a
elem_at [] _ = error "Need non-empty list"
elem_at x n | len x <= n = error ("n too large " ++ show (len x))
            | n < 0      = error "Need positive n"
            | otherwise  = elem_at_r x n 
  where
    len :: [a] -> Int 
    len x = sum [ 1 | a <- x]

    elem_at_r :: [a] -> Int -> a
    elem_at_r x n | n == 0     = head x
                  | 0 < n      = elem_at_r (tail x) (n-1)

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