haskell和函数的类型定义。几个问题
如果我做了haskell和函数的类型定义。几个问题,haskell,function,types,definition,type-inference,Haskell,Function,Types,Definition,Type Inference,如果我做了anyisupper“asBsd”,我将得到True 这里,any的第二个元素是字符串。 但是,如果我这样做: any ("1" `isInfixOf`) ["qas","123","=-0"] any的第二个元素是字符串列表。 这两个函数之间的差异是如何产生的,为什么会产生这种差异 另一个例子。 如果我写过滤器isUpper“asdVdf”,我将得到“V” 这里,要筛选的第二个元素是字符串。 但是,如果我这样写: 过滤器(isUpper.head)[“abc”、“Vdh”、“12”
anyisupper“asBsd”
,我将得到True
这里,
any
的第二个元素是字符串。但是,如果我这样做:
any ("1" `isInfixOf`) ["qas","123","=-0"]
any
的第二个元素是字符串列表。这两个函数之间的差异是如何产生的,为什么会产生这种差异 另一个例子。
如果我写
过滤器isUpper“asdVdf”
,我将得到“V”
这里,要筛选的第二个元素是字符串。
但是,如果我这样写:
过滤器(isUpper.head)[“abc”、“Vdh”、“12”]
,我将获得[“Vdh”]
如您所见,要筛选的第二个元素现在是字符串列表。
为什么会有差异,haskell如何知道这两种情况都是正确的 总而言之:
我不明白在同一个函数中,一次haskell得到第二个字符串元素,另一次haskell得到第二个元素中的字符串列表。
一次发生在
any
函数中,另一次发生在filter
函数中。哈斯克尔(和我)怎么知道这两种情况都是对的
谢谢:-)。字符串实际上就是字符列表,一个
[Char]
。如果你喜欢,“hello”是['h','e','l','l','o']
的缩写。因此,在这两种情况下,你都会得到一个列表,一个是字符列表,另一个是字符串列表(或者字符列表,如果你喜欢)。因为isUpper
是Char->Bool
函数,而是“1”'isInfixOf'
和isUpper。head
是[Char]->Bool
函数
可以重写为
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
的类型是Char->Bool
。因此:
any :: (a -> Bool) -> [a] -> Bool
isUpper :: (Char -> Bool)
//∴ a = Char and
any isUpper :: [a] -> Bool
= [Char] -> Bool
因此anyisupper
只需要获取字符串,而不是字符串列表
最后,isUpper。头部
。在Haskell中,相关函数的类型为:
filter :: (a -> Bool) -> [a] -> [a]
head :: [a] -> a
isUpper :: Char -> Bool
(.) :: (b -> c) -> (a -> b) -> a -> c
因此,对于过滤器isUpper
,a=Char
,类型为[Char]->[Char]
,即需要将字符串作为参数
和2:
因此,对于过滤器(isUpper.head)
,我们有a=[Char]
,类型是[[Char]]->[[Char]]]
,即需要将字符串列表作为参数
注:
isInfixOf
的类型实际上是(等式a)=>[a]->[a]->[a]->Bool
,因为等式必须对类型a
有效,但这与我们的分析无关
我已经临时将head
的变量a
更改为b
,但这并不重要
嗯,那是多态性。any
的类型是(a->Bool)->[a]->Bool
,其中类型变量a
可以是您喜欢的任何类型。在第一种情况下,它是Char
,因为第二个参数是Char
s的列表,类型变成(Char->Bool)->String->Bool
(请记住[Char]
与String
相同);在第二个a
是String
,类型变成(String->Bool)->[String]->Bool
filter
的推理是类似的。问题到底是什么?类型推断是Haskell的一个主要功能,任何文本甚至参数模式都会触发它。我不明白Haskell如何在一次中获得第二个参数,即字符串,而在另一次中,Haskell在第二个参数中获得字符串列表,这两种情况发生在同一个函数中。一次在any
中,另一次在filter
中。哈斯克尔(和我)怎么知道这两种情况都是对的?我需要一个解释:-)这是一个好问题,肯尼特的回答非常好。但是,如果您可以编辑问题以包含您的澄清,则会有所帮助。这样,将来发现这个问题的人都能更好地理解。如果你觉得不清楚的话,我可以把它换成别的东西:-)。可能有用的东西。我不知道这是否只是GHC的一个特性,或者所有Haskell实现都是这样做的,但是您可以键入:t
来查找某个东西的类型。例如,如果您键入:t any
,您将得到:any::(a->Bool)->[a]->Bool
。因此,它需要一个类型为a->Bool
的函数和一个a
的列表,并返回一个Bool
。首先,非常感谢您给出了非常详细的回答!。我想我明白你说的,但我有一个问题。在filter(isUpper.head)
中,a=[Char]
,由于filter的类型签名是filter::(a->Bool)->[a]->[a]
,(a->Bool)
函数实际上是一个([Char]->Bool)
函数,因此我们应该有[[Char]]
在过滤器的第二个元素中,因为如果a
实际上是[Char]
,那么[a]
实际上比a
高一级,应该是[Char]
。我说得对吗?非常感谢:-)还有一件事,我不知道什么是isIndexOf
或indexOf
filter :: (a -> Bool) -> [a] -> [a]
head :: [a] -> a
isUpper :: Char -> Bool
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) :: (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