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