简体   繁体   English

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

[英]haskell and type definition of functions. couple of questions

if i do any isUpper "asBsd" , i'll get True . 如果我做any isUpper "asBsd" ,我会得到True
here, the second element to any is a string. 这里, any的第二个元素是一个字符串。
but, if i do this: 但是,如果我这样做:

any ("1" `isInfixOf`) ["qas","123","=-0"]

the second element to any is a list of strings. any的第二个元素是字符串列表。
how and why this difference between those 2 functions? 如何以及为什么这两个功能之间存在差异?

another example. 另一个例子。
if i write filter isUpper "asdVdf" , i'll get "V" . 如果我写过filter isUpper "asdVdf" ,我会得到"V"
here, the second element to filter, is a string. 这里,要过滤的第二个元素是一个字符串。
but, if i write this: 但是,如果我写这个:
filter (isUpper . head) ["abc","Vdh","12"] , i'll get ["Vdh"] . filter (isUpper . head) ["abc","Vdh","12"] ,我会得到["Vdh"]
as you can see, the second element to filter is now a list of strings. 如您所见,要过滤的第二个元素现在是一个字符串列表。
why there is a differences and how haskell know's it's right in both cases? 为什么存在差异以及haskell如何知道它在两种情况下都是正确的?

to summarize it: 总结一下:
i don't understand how in the same function, one time haskell get a second element that is a string, and in other time, haskell get a list of strings, in the second element. 我不明白在同一个函数中,有一次haskell得到第二个元素是一个字符串,而在其他时候,haskell得到一个字符串列表,在第二个元素中。
one time it happened in any function, and the other time in filter function. 有一次它发生在any函数中,另一次发生在filter函数中。
how haskell(and me) know's it's right in both cases? haskell(和我)怎么知道它在两种情况下都是正确的?

thanks :-). 谢谢 :-)。

Because isUpper is a Char -> Bool function and "1" 'isInfixOf' and isUpper . head 因为isUpperChar -> Bool函数,而"1" 'isInfixOf'isUpper . head isUpper . head are [Char] -> Bool functions isUpper . head[Char] -> Bool函数


"1" `isInfixOf` xxx

can be rewritten as 可以改写为

isInfixOf "1" xxx

We knew the type of isInfixOf is [a] -> [a] -> Bool 1 . 我们知道isInfixOf的类型是[a] -> [a] -> Bool 1 Now the first argument to isInfixOf is "1" which is of type [Char] , so we can deduce a is a Char : 现在isInfixOf的第一个参数是"1" ,它的类型为[Char] ,所以我们可以推导出aChar

     isInfixOf :: [a]    -> [a] -> Bool
       "1"     :: [Char]
//∴ a = Char and
 isInfixOf "1" ::           [a] -> Bool
                =        [Char] -> Bool

That means isInfixOf "1" is now a [Char] -> Bool function. 这意味着isInfixOf "1"现在是[Char] -> Bool函数。

Now, the type of any is (a -> Bool) -> [a] -> Bool function. 现在, any的类型是(a -> Bool) -> [a] -> Bool函数。 As above, 如上,

               any :: (a      -> Bool) -> [a] -> Bool
     isInfixOf "1" :: ([Char] -> Bool)
 //∴ a = [Char] and

any (isInfixOf "1") :: [a] -> Bool = [[Char]] -> Bool any(isInfixOf“1”):: [a] - > Bool = [[Char]] - > Bool

In order to satisfy with the type constraint of any (isInfixOf "1") , the argument must be a string list. 为了满足any (isInfixOf "1")类型约束any (isInfixOf "1") ,参数必须是字符串列表。


Now consider isUpper . 现在考虑isUpper The type of isUpper is Char -> Bool . isUpper的类型是Char -> Bool Hence: 因此:

              any :: (a    -> Bool) -> [a] -> Bool
          isUpper :: (Char -> Bool)
//∴ a = Char and
      any isUpper ::                   [a] -> Bool
                   =                [Char] -> Bool

So any isUpper needs to take a string only, instead of a string list. 所以any isUpper需要一个字符串,而不是一个字符串列表。


Finally, isUpper . head 最后, isUpper . head isUpper . head . isUpper . head In Haskell, the types of the relevant functions are: 在Haskell中,相关函数的类型是:

 filter :: (a -> Bool) -> [a] -> [a]
   head :: [a] -> a
isUpper :: Char -> Bool
    (.) :: (b -> c) -> (a -> b) -> a -> c

Hence for filter isUpper , a = Char and the type is [Char] -> [Char] , ie it needs to take a string as parameter. 因此,对于filter isUppera = Char ,类型为[Char] -> [Char] ,即需要将字符串作为参数。

And 2 : 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

Thus for filter (isUpper . head) , we have a = [Char] and the type is [[Char]] -> [[Char]] , ie it needs to take a string list as parameter. 因此对于filter (isUpper . head) ,我们有a = [Char] ,类型是[[Char]] -> [[Char]] ,即需要将字符串列表作为参数。


Note: 注意:

  1. The type of isInfixOf is actually (Eq a) => [a] -> [a] -> Bool as the equality must be valid for type a , but this is irrelevant in our analysis. isInfixOf的类型实际上是(Eq a) => [a] -> [a] -> Bool因为等式必须对类型a有效,但这与我们的分析无关。
  2. I've temporarily changed the variable a to b for head , but it doesn't matter. 我临时改变的变量abhead ,但它并不重要。

A String is actually just list of characters, a [Char] . String实际上只是字符列表, [Char] So if you like, "hello" is shorthand for ['h', 'e', 'l', 'l', 'o'] . 所以,如果你愿意,“你好”是['h', 'e', 'l', 'l', 'o']简写。 Therefore in both cases, you're getting a list of something, it's just that one case is a list of Char and the other case is a list of Strings (or a list of lists of chars, if you like). 因此,在这两种情况下,你都会得到一些东西,只是一个案例是Char的列表,另一个案例是一个字符串列表(或者你喜欢的字符列表列表)。

Well, that's polymorphism. 嗯,这是多态性。 The type of any is (a -> Bool) -> [a] -> Bool where the type variable a can be anything you like. any的类型是(a -> Bool) -> [a] -> Bool ,其中类型变量a可以是你喜欢的任何东西。 In the first case it's Char - because the second argument is a list of Char s - and the type becomes (Char -> Bool) -> String -> Bool (remember that [Char] is the same as String !); 在第一种情况下它是Char - 因为第二个参数是Char的列表 - 并且类型变为(Char -> Bool) -> String -> Bool (记住[Char]String相同!); in the second a is String and the type becomes (String -> Bool) -> [String] -> Bool . 在第二个aString ,类型变为(String -> Bool) -> [String] -> Bool

The reasoning for filter is similar. filter的推理类似。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM