In the ad type
f :: (T a) => String => a
T is a type class (typeclass), String is a type, a is any type belonging to a type class T
Int , Integer , Char , String are all types. Class types denote the type of certain "methods" (if expressed in terms of OOP), that is, it is something like interfaces or abstract classes.
For example:
class T a where f :: a -> Int g :: a -> Int gx = (fx) ^ 2
Here we declare a type class T such that for any type a belonging to T , there exists a function f type f :: a -> Int . Also to the variable of this type a you can apply the function g , which has already been implemented. Now we can make an already existing type (let it be a String ) an instance of the class T :
instance T String where f = length
Thus, for the type String function f returns the length of the string:
f "hello" -- вернёт 5 g "hello" -- вернёт (fx) ^ 2, или 25
The implemented function g can also be redefined in a class instance:
instance T Int where fx = x gx = x + x
Now, back to your example. The cc function signature should look like this:
cc :: [String] -> String
this means that the cc function takes a list of strings and returns a string. But generally using strings to represent different types of values is a very bad idea (especially in Haskell, with its terrific type system). Usually, algebraic data types are used instead ( sealed classes in some object-oriented languages). I do not know what types of values you have, but I will give an example with a list of different numbers ( Int and Float ) that need to be added together (I remind you that the operator (+) :: (Num a) => a -> a -> a in Haskell accepts two numbers of the same type belonging to the class of types Num - you can add either a whole with an integer, or a fractional with a fractional, but a whole with a fractional - you cannot):
data MyNumber = MyInt Int | MyFloat Float mySum :: [MyNumber] -> MyNumber mySum = foldl myAdd (MyInt 0) myAdd :: MyNumber -> MyNumber -> MyNumber myAdd (MyInt x) (MyInt y) = MyInt $ x + y myAdd (MyInt x) (MyFloat y) = MyFloat $ (fromIntegral x) + y myAdd f@(MyFloat x) i@(MyInt y) = myAdd if myAdd (MyFloat x) (MyFloat y) = MyFloat $ x + y