开发者

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

开发者 https://www.devze.com 2023-03-06 16:10 出处:网络
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

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)
0

精彩评论

暂无评论...
验证码 换一张
取 消