Поскольку isUpper
является функцией Char -> Bool
, а "1" ‘isInfixOf‘
и isUpper . head
являются [Char] -> Bool
функциями
"1" `isInfixOf` xxx
можно переписать как
isInfixOf "1" xxx
Мы знали, что тип isInfixOf
равен [a] -> [a] -> Bool
1 . Теперь первый аргумент isInfixOf
- это "1"
, который имеет тип [Char]
, так что мы можем вывести a
это Char
:
isInfixOf :: [a] -> [a] -> Bool
"1" :: [Char]
//∴ a = Char and
isInfixOf "1" :: [a] -> Bool
= [Char] -> Bool
Это означает, что isInfixOf "1"
теперь является функцией [Char] -> Bool
.
Теперь тип any
является функцией (a -> Bool) -> [a] -> Bool
. Как указано выше,
any :: (a -> Bool) -> [a] -> Bool
isInfixOf "1" :: ([Char] -> Bool)
//∴ a = [Char] and
любой (isInfixOf "1") :: [a] -> Bool
= [[Char]] -> Bool
Чтобы удовлетворить ограничения типа any (isInfixOf "1")
, аргумент должен быть списком строк.
Теперь рассмотрим isUpper
. Тип isUpper
является Char -> Bool
. Следовательно:
any :: (a -> Bool) -> [a] -> Bool
isUpper :: (Char -> Bool)
//∴ a = Char and
any isUpper :: [a] -> Bool
= [Char] -> Bool
Так что any isUpper
нужно взять только строку вместо списка строк.
Наконец, isUpper . head
. В Haskell типы соответствующих функций:
filter :: (a -> Bool) -> [a] -> [a]
head :: [a] -> a
isUpper :: Char -> Bool
(.) :: (b -> c) -> (a -> b) -> a -> c
Следовательно, для filter isUpper
, a = Char
и типа [Char] -> [Char]
, т. Е. Ему нужно принять строку в качестве параметра.
И 2
(.) :: (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
Таким образом, для filter (isUpper . head)
у нас есть a = [Char]
, а типом является [[Char]] -> [[Char]]
, то есть он должен принимать список строк в качестве параметра.
Примечание:
- Тип
isInfixOf
на самом деле (Eq a) => [a] -> [a] -> Bool
, поскольку равенство должно быть допустимым для типа a
, но это не имеет значения в нашем анализе.
- Я временно изменил переменную
a
на b
для head
, но это не имеет значения.