由于isUpper
是一个Char -> Bool
函数,而"1" ‘isInfixOf‘
和isUpper . head
都是[Char] -> Bool
函数。
"1" `isInfixOf` xxx
可以重写为
isInfixOf "1" xxx
我们知道 isInfixOf
的类型是 [a] -> [a] -> Bool
1。现在传递给 isInfixOf
的第一个参数是类型为 [Char]
的 "1"
,因此我们可以推断出 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]
,即需要接受一个字符串作为参数。
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
因此对于
filter (isUpper . head)
,我们有
a = [Char]
,类型为
[[Char]] -> [[Char]]
,即它需要接受一个字符串列表作为参数。注意:1.
isInfixOf
的类型实际上是
(Eq a) => [a] -> [a] -> Bool
,因为相等性必须对类型
a
有效,但这在我们的分析中是无关紧要的。2. 我们暂时将变量
a
更改为
b
,但这并不重要。
any
函数中,而另一次则出现在filter
函数中。那么,Haskell(以及我)怎么知道在这两种情况下都是正确的呢?我需要解释一下 :) - Azriel:t <something>
来查找某个东西的类型。例如,如果你输入:t any
,你会得到:any :: (a -> Bool) -> [a] -> Bool
。因此,它接受一个类型为a -> Bool
的函数和一个a
类型的列表,并返回一个Bool
类型的值。 - Tyler