如果我any isUpper "asBsd"
,我会得到True
这里,any
的第二个元素是一个字符串
但是,如果我这样做:
any ("1" `isInfixOf`) ["qas","123","=-0"]
any
的第二个元素是字符串列表
这两种功能之间的区别如何?为什么?
filter isUpper "asdVdf"
,我会得到"V"
这里,要过滤的第二个元素是一个字符串
但是,如果我这样写:filter (isUpper . head) ["abc","Vdh","12"]
,我会["Vdh"]
如您所见,要过滤的第二个元素现在是字符串列表
为什么存在差异以及haskell如何知道它在两种情况下都是正确的?
总结一下:
我不明白在同一个函数中,有一次haskell得到第二个元素是一个字符串,而在其他时候,haskell得到一个字符串列表,在第二个元素中。
一次发生在any
函数中,另一次发生在filter
函数中
haskell(和我)怎么知道它在两种情况下都是正确的?
谢谢: - )。
答案 0 :(得分:11)
因为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
any(isInfixOf“1”):: [a] - >布尔 = [[Char]] - >布尔
为了满足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
,但这无所谓。答案 1 :(得分:5)
String实际上只是一个字符列表,[Char]
。所以,如果你愿意,“你好”是['h', 'e', 'l', 'l', 'o']
的简写。因此,在这两种情况下,你得到一个东西的列表,只是一个案例是一个Char列表,另一个案例是一个字符串列表(或者一个字符列表列表,如果你愿意的话)。
答案 2 :(得分:4)
嗯,这是多态性。 any
的类型为(a -> Bool) -> [a] -> Bool
,其中类型变量a
可以是您喜欢的任何内容。在第一种情况下它是Char
- 因为第二个参数是Char
s的列表 - 类型变为(Char -> Bool) -> String -> Bool
(请记住[Char]
与{{1}相同}})!;第二个String
中的a
为String
,类型为(String -> Bool) -> [String] -> Bool
。
filter
的推理类似。