haskell和函数的类型定义。几个问题

时间:2010-02-23 10:43:52

标签: haskell function types definition type-inference

如果我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(和我)怎么知道它在两种情况下都是正确的?

谢谢: - )。

3 个答案:

答案 0 :(得分:11)

因为isUpperChar -> Bool函数而"1" ‘isInfixOf‘isUpper . head[Char] -> Bool函数


"1" `isInfixOf` xxx

可以改写为

isInfixOf "1" xxx

我们知道isInfixOf的类型是[a] -> [a] -> Bool 1 。现在,isInfixOf的第一个参数是"1" [Char]类型,因此我们可以推断aChar

     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")的类型约束,参数必须是字符串列表。


现在考虑isUpperisUpper的类型为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 isUppera = 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]],即需要将字符串列表作为参数。


注意:

  1. isInfixOf的类型实际上是(Eq a) => [a] -> [a] -> Bool,因为等式必须对类型a有效,但这与我们的分析无关。
  2. 我暂时将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中的aString,类型为(String -> Bool) -> [String] -> Bool

filter的推理类似。