Home > Net >  How to convert a [Int] to [Int] on haskell
How to convert a [Int] to [Int] on haskell

Time:12-06

I need to receive a list [Int] and calculate the value of the elements and return a list with the sum value. But if the sum value > 9 the list will be (example) [5,6]. But if not < 10 the list will be (example) [0,9] I have done it and doesn't work

size_list :: [Int] -> Int
size_list [] = 0
size_list (x:xs) = x   size_list xs

digitVerify :: [Int] -> [Int]
digitVerify [] = []
digitVerify l = if ((size_list l) > 9)
                     then
                     (div (size_list l) 10) : (mod (size_list l) 10)
                     else
                     0 : (size_list l)

CodePudding user response:

The second parameter of the : has to be a list even if empty [].

Error: 0 : 3
[0,3]: 0 : 3 : []

size_list :: [Int] -> Int
size_list [] = 0
size_list (x:xs) = x   size_list xs

digitVerify :: [Int] -> [Int]
digitVerify [] = []
digitVerify l = if ((size_list l) > 9)
                     then
                     (div (size_list l) 10) : (mod (size_list l) 10) : []
                     else
                     0 : (size_list l) : []

Test:

digitVerify [3]
digitVerify [50,6]

Output:

[0,3]
[50,6]

CodePudding user response:

You're almost there.

Compiling the code in question throws the following errors, which are two instances of the same thing:

fold.hs:9:48: error:
    • Couldn't match expected type ‘[Int]’ with actual typeIntIn the second argument of ‘(:)’, namely ‘(mod (size_list l) 10)’
      In the expression: (div (size_list l) 10) : (mod (size_list l) 10)
      In the expression:
        if ((size_list l) > 9) then
            (div (size_list l) 10) : (mod (size_list l) 10)
        else
            0 : (size_list l)
  |
9 |                      (div (size_list l) 10) : (mod (size_list l) 10)
  |                                                ^^^^^^^^^^^^^^^^^^^^

fold.hs:11:27: error:
    • Couldn't match expected type ‘[Int]’ with actual typeIntIn the second argument of ‘(:)’, namely ‘(size_list l)’
      In the expression: 0 : (size_list l)
      In the expression:
        if ((size_list l) > 9) then
            (div (size_list l) 10) : (mod (size_list l) 10)
        else
            0 : (size_list l)
   |
11 |                      0 : (size_list l)
   |                           ^^^^^^^^^^^

Why is this?

Taking the first example, you are calling the operator : to create your list, with two arguments: div (size_list l) 10 and mod (size_list l) 10. (: is actually syntax sugar for a constructor, not a function, but we can ignore this distincton in this case.)

What is the type of :?

A GHCi session tells us:

Prelude> :type (:)
(:) :: a -> [a] -> [a]

(:) takes a value of type a and a list of as, and returns a list of as, which is the second argument with the first argument prepended to it.

Because you passed an Int as the first argument, GHC expects a [Int] as the second argument, but you've given it an Int, hence the error.

Instead, to create a two-element list like this, you have a number of options:

  • Use the list literal syntax:

    [div (size_list l) 10, mod (size_list l) 10]
    
  • Use the : operator associatively, but put the empty list at the end of the chain:

    div (size_list l) 10 : mod (size_list l) 10 : []
    

    : associates right, so this is the equivalent of

    div (size_list l) 10 : (mod (size_list l) 10 : [])
    

    which is valid, if you think about it.

  • Concatenate singleton lists:

    [div (size_list l) 10]    [mod (size_list l) 10]
    

However, since this function always returns a two-element list, it's probably more appropriate for it to return a tuple, i.e. digitVerify should have the type [Int] -> (Int, Int).

I'll leave you to explore that option, if you get stuck you can just come back and ask another question.

Happy Haskelling!

  • Related