Error message: "Couldn't match expected type '[n]' with actual type'([Int], [Integer])'

import System.IO
import Data.List

--This function will take a string composed of A, B, and C and return an Integer list
--composed of 1, 2, and 3.
check_order :: String -> [Int]
check_order "" = []
check_order (x:xs)
    | x `elem` "A" = 1 : check_order xs
    | x `elem` "B" = 2 : check_order xs
    | otherwise    = 3 : check_order xs
-- Takes the integer array generated from check_order and an arbitrary
-- integer array of length 3 and returns a String correlating the check_order
-- array and the arbitrary integer array
number_correction :: (Integral n, Show n) => [n] -> [n] -> String
number_correction [] _ = ""
number_correction (x:xs) num_array
    | x == 1 = show min_num ++ " " ++ number_correction xs num_array
    | x == 2 = show median_num ++ " " ++ number_correction xs num_array
    | otherwise = show max_num ++ " " ++ number_correction xs num_array
    where max_num = num_array !! 2
          median_num = num_array !! 1
          min_num = num_array !! 0
main = do
       let test = "ABCBABBAC";
       let num_array = [6, 1, 8];
       let ordered_list = check_order(test);
       print(ordered_list)
       
       let new_string = number_correction(ordered_list, num_array);
       
       print(new_string)
       

[1 of 1] Compiling Main             ( main.hs, main.o )
main.hs:30:42: error:• Couldn't match expected type ‘[n]’
                  with actual type ‘([Int], [Integer])’
    • In thefirst argument of ‘number_correction’, namely
        ‘(ordered_list, num_array)’
      In the expression: number_correction (ordered_list, num_array)
      In an equation for‘new_string’:
          new_string = number_correction (ordered_list, num_array)
    • Relevant bindings include
        new_string :: [n] -> String (bound at main.hs:30:12)

The problem is how you’re passing arguments to number_correction. In Haskell, a function only has one argument. This is true of number_correction. The twist is that when you pass in this argument, you get back a new function, and you pass the second argument to that. So write (number_correction ordered_list) num_array or more idiomatically just number_correction ordered_list num_array.

tldr: in you’re trying to pass in multiple arguments, you can’t pass them in like this.

1 Like

There are two ways to pass arguments to a Haskell function:

  1. Individual arguments

  2. A tuple

Individual arguments are done the way that you have defined the function number_correction, with spaces between the arguments:

number_correction :: (Integral n, Show n) => [n] -> [n] -> String
number_correction [] _ = ""
number_correction (x:xs) num_array

The other way to do this is as a tuple, written in parentheses, thus: (a,b). Pattern matching means that the tuple is split up automatically:

number_correction :: (Integral n, Show n) => ([n],[n]) -> String
number_correction ([],_) = ""
number_correction ((x:xs),num_array)

When you call the function, you are using a tuple:

let new_string = number_correction(ordered_list, num_array)

This matches the tuple definition, but not the individual argument definition:

main.hs:30:42: error:• Couldn't match expected type ‘[n]’
              with actual type ‘([Int], [Integer])’

Hence the error.

Individual arguments is the way to go. Try this instead:

let new_string = number_correction ordered_list num_array

And likewise for all of your function calls.

You also don’t need the semicolons.