如何为自定义List类型实现sumL :: List Int -> Int求和函数?
Absolutely you can implement sumL! Let's walk through how to do this, starting with understanding your custom List type.
Breaking Down Your List Structure
Your List has a unique recursive structure that's different from Haskell's standard list:
EmptyLis the empty list, just like[]ConsL a (List (a,a))means each non-empty node holds a value of typea, followed by a list where every element is a pair ofas. This creates a nested hierarchy: aList Intwill have plain Ints at the top level, pairs of Ints in the next level, pairs of those pairs in the level after that, and so on.
To calculate the total sum, we need to add up every value at every level—including the values nested inside pairs. A type class is the cleanest way to handle this nested summation.
Implementation Code
First, define a type class to handle any type we can convert into an Int sum:
class Sumable a where sumIt :: a -> Int -- For plain Ints, we just return the value itself instance Sumable Int where sumIt = id -- For pairs, sum each element and add the results together instance (Sumable a, Sumable b) => Sumable (a, b) where sumIt (x, y) = sumIt x + sumIt y
Then, write a polymorphic helper function that works with any List of Sumable values, and use it to define sumL:
sumL :: List Int -> Int sumL = sumHelper -- This helper handles any List where elements can be summed (via Sumable) sumHelper :: Sumable a => List a -> Int sumHelper EmptyL = 0 sumHelper (ConsL val rest) = sumIt val + sumHelper rest
Testing the Implementation
Let's verify with some examples:
sumL EmptyLreturns0(sum of an empty list is always 0)sumL (ConsL 5 EmptyL)returns5(single top-level element)sumL (ConsL 3 (ConsL (2,4) EmptyL))returns3 + 2 + 4 = 9sumL (ConsL 1 (ConsL (2,3) (ConsL ((4,5),(6,7)) EmptyL)))returns1 + 2 + 3 + 4 + 5 + 6 + 7 = 28
Why This Works
The Sumable type class lets us recursively unpack nested pairs: every time we hit a pair, we split it into its two parts, sum each part, and add those sums together. The sumHelper function then traverses every node of your custom List, applying sumIt to each element and accumulating the total.
This approach is extensible too—if you later wanted to sum a List of triples or other nested types, you could just add a new Sumable instance.
内容的提问来源于stack exchange,提问作者Yahatma Amid

