haskell and type definition of functions. couple of questions

definition, function, haskell, type-inference, types

Solution

Because `isUpper` is a `Char -> Bool` function and `"1" ‘isInfixOf‘` and `isUpper . head` are `[Char] -> Bool` functions

"1" `isInfixOf` xxx

can be rewritten as

isInfixOf "1" xxx

We knew the type of `isInfixOf` is `[a] -> [a] -> Bool`1. Now the first argument to `isInfixOf` is `"1"` which is of type `[Char]`, so we can deduce `a` is a `Char`:

     isInfixOf :: [a]    -> [a] -> Bool
       "1"     :: [Char]
//∴ a = Char and
 isInfixOf "1" ::           [a] -> Bool
                =        [Char] -> Bool

That means `isInfixOf "1"` is now a `[Char] -> Bool` function.

Now, the type of `any` is `(a -> Bool) -> [a] -> Bool` function. As above,

               any :: (a      -> Bool) -> [a] -> Bool
     isInfixOf "1" :: ([Char] -> Bool)
 //∴ a = [Char] and

any (isInfixOf "1") :: [a] -> Bool = [[Char]] -> Bool

In order to satisfy with the type constraint of `any (isInfixOf "1")`, the argument must be a string list.

Now consider `isUpper`. The type of `isUpper` is `Char -> Bool`. Hence:

              any :: (a    -> Bool) -> [a] -> Bool
          isUpper :: (Char -> Bool)
//∴ a = Char and
      any isUpper ::                   [a] -> Bool
                   =                [Char] -> Bool

So `any isUpper` needs to take a string only, instead of a string list.

Finally, `isUpper . head`. In Haskell, the types of the relevant functions are:

 filter :: (a -> Bool) -> [a] -> [a]
   head :: [a] -> a
isUpper :: Char -> Bool
    (.) :: (b -> c) -> (a -> b) -> a -> c

Hence for `filter isUpper`, `a = Char` and the type is `[Char] -> [Char]`, i.e. it needs to take a string as parameter.

And2:

            (.) :: (b    -> c   ) -> (a   -> b) -> a -> c
        isUpper :: (Char -> Bool)
           head ::                   ([b] -> b)
//∴ c = Bool, b = Char, a = [b] = [Char], and
 isUpper . head ::                                 a -> c
                =                             [Char] -> Bool

Thus for `filter (isUpper . head)`, we have `a = [Char]` and the type is `[[Char]] -> [[Char]]`, i.e. it needs to take a string list as parameter.

Note:

- The type of `isInfixOf` is actually `(Eq a) => [a] -> [a] -> Bool` as the equality must be valid for type `a`, but this is irrelevant in our analysis.

- I've temporarily changed the variable `a` to `b` for `head`, but it doesn't matter.

Problem

if i do `any isUpper "asBsd"`, i'll get `True`. here, the second element to `any` is a string. but, if i do this: ``` any ("1" `isInfixOf`) ["qas","123","=-0"] ``` the second element to `any` is a list of strings. how and why this difference between those 2 functions? another example. if i write `filter isUpper "asdVdf"` , i'll get `"V"`. here, the second element to filter, is a string. but, if i write this: `filter (isUpper . head) ["abc","Vdh","12"]` , i'll get `["Vdh"]`. as you can see, the second element to filter is now a list of strings. why there is a differences and how haskell know's it's right in both cases? to summarize it: i don't understand how in the same function, one time haskell get a second element that is a string, and in other time, haskell get a list of strings, in the second element. one time it happened in `any` function, and the other time in `filter` function. how haskell(and me) know's it's right in both cases? thanks :-).

Original source