简体   繁体   English

了解功能的类型

[英]Understanding the types of functions

I am trying to understand the types of functions and being able to explain them. 我试图理解函数的类型并能够解释它们。

Two functions: 两个功能:

insert :: t -> Bool -> ([t],[t]) -> ([t],[t])
insert a True (b,c) = (a:b,c)
insert a False (b,c) = (b,a:c)

partition :: (t -> Bool) -> [t] -> ([t],[t])
partition p [] = ([],[])
partition p (x : xs) = insert x (p x) (partition p xs)

From my limited knowledge I think that insert function: 从我有限的知识,我认为插入功能:

  • insert is of type t, it takes two arguments one of bool and one of a tuple of two lists of type t and returns a tuple of two lists of type t. insert是t类型,它接受两个参数bool和两个类型为t的列表之一,并返回两个t类型列表的元组。

  • partition is a tuple of type t which returns a bool, and it takes a list of type t as it's argument and returns a tuple of two lists of type t. partition是类型为t的元组,它返回一个bool,它接受一个类型为t的列表作为参数,并返回两个类型为t的列表的元组。

Is that the right way of thinking about it or am I getting it wrong? 这是正确的思考方式还是我弄错了? I have been following some tutorials and this is what I've u nderstood so far. 我一直在关注一些教程,这是我到目前为止所理解的。

insert is of type t , it takes two arguments one of Bool and one of a tuple of two lists of type t and returns a tuple of two lists of type t . insertt类型,它接受Bool两个参数和两个类型为t列表中的一个元组,并返回两个类型为t列表的元组。

No . First of all it is important to notice that in Haskell each function takes exactly one parameter. 首先,它注意到在Haskell每个函数带一个参数是非常重要的。 Indeed 确实

insert :: t -> Bool -> ([t],[t]) -> ([t],[t])

is a short and compact form of: 是一种简短紧凑的形式:

insert :: t -> (Bool -> (([t],[t]) -> ([t],[t])))

in fact the above is still not very verbose, a canonical form would be: 事实上,上述内容仍然不是很冗长,规范形式如下:

insert :: ((->) t) (((->) Bool) (((->) ((,) ([] t)) ([] t))  ((,) ([] t)) ([] t)))

but the above is of course not very readable, let us thus stick to the second form. 但上面当然不是很易读,所以让我们坚持第二种形式。

Each function in Haskell takes exactly one parameter. Haskell中的每个函数只需要一个参数。 What here happens is that the result of applying a parameter to a certain function, generates a new function. 什么这里发生的是应用参数有一定作用的结果 ,产生了新的功能。

So if we would generate an expression insert x , we have constructed a function of the type Bool -> (([t], [t]) -> ([t], [t])) . 因此,如果我们生成一个表达式insert x ,我们构造了一个Bool -> (([t], [t]) -> ([t], [t]))类型的函数。

Informally , one indeed sometimes says that a " function takes n parameters ". 非正式地 ,人们确实有时会说“ 函数需要n个参数 ”。 But it is important to keep that in mind. 但重要的是要记住这一点。

Secondly you forgot about the t . 其次你忘了t We can informally say that insert takes three parameters, a value of type t , a boolean (type Bool ), and a 2-tuple with two lists of t s. 我们可以非正式地说insert三个参数,一个是t类型的值,一个boolean(类型为Bool ),一个带有两个t s列表的2元组。 It will return a 2-tuple of two lists of t s. 它将返回两个t的两个元组列表。 Depending on whether the Bool is True or False it prepends one of the two lists with the given value. 根据BoolTrue还是False它会在两个列表中添加给定值之一。

For example: 例如:

Prelude> insert 5 False ([], [])
([],[5])
Prelude> insert 5 False ([1,4], [2,5])
([1,4],[5,2,5])
Prelude> insert 5 True ([1,4], [2,5])
([5,1,4],[2,5])
Prelude> insert 3 True ([1,4], [2,5])
([3,1,4],[2,5])
Prelude> insert 3 False ([1,4], [2,5])
([1,4],[3,2,5])

partition is a tuple of type t which returns a bool , and it takes a list of type t as it's argument and returns a tuple of two lists of type t . partition是类型为t的元组,它返回一个bool ,它接受一个类型为t的列表作为参数,并返回两个类型为t列表的元组。

No, the parameter here has type (t -> Bool) that is a function . 不,这里的参数有一个函数类型(t -> Bool) Indeed in Haskell you can pass functions as parameters. 实际上,在Haskell中,您可以将函数作为参数传递。

Informally we can say that partition takes a " predicate " (a function that maps values to Bool s) and a list of t s, and it returns a 2-tuple with two lists of t s. 非正式地,我们可以说partition采用“ 谓词 ”(将值映射到Bool的函数)和t s列表,并返回带有两个t s列表的2元组。 Depending on whether the predicate holds for the values in the list, these are sorted in the first or the second list in the 2-tuple. 根据谓词是否适用于列表中的值,这些值将在2元组的第一个或第二个列表中排序。

For example: 例如:

Prelude> partition (>3) [1,4,2,5]
([4,5],[1,2])
Prelude> partition (>3) [1,3,0,2]
([],[1,3,0,2])
Prelude> partition (>3) [1,7,8,0]
([7,8],[1,0])
Prelude> partition (>3) [1,7,8,9]
([7,8,9],[1])

No, the types are exactly as shown: 不,类型完全如图所示:

insert has type t -> Bool -> ([t], [t]) -> ([t], [t]) , which means it is a function that takes a value of type t as an argument and returns a function of type Bool -> ([t], [t]) -> ([t], [t]) . insert有类型t -> Bool -> ([t], [t]) -> ([t], [t]) ,这意味着它是一个函数,它将t类型的值作为参数并返回一个函数Bool -> ([t], [t]) -> ([t], [t])类型Bool -> ([t], [t]) -> ([t], [t]) Informally, you can think of insert as a function that takes 3 arguments: one of type t , one of type Bool , and one of type ([t], [t]) , and returns another value of type ([t], [t]) . 非正式地,您可以insert视为一个带有3个参数的函数:一个是t类型,一个是Bool类型,另一个是类型([t], [t]) ,并返回另一个类型的值([t], [t])

partition is a function that takes another function (of type t -> Bool ) as its argument, and returns a function of type [t] -> ([t],[t]) . partition是一个函数,它接受另一个函数(类型为t -> Bool )作为参数,并返回一个类型为[t] -> ([t],[t]) Again informally, you can think of partition as taking two arguments (of type t -> Bool and type [t] ) and returning a value of type ([t], [t]) . 非正式地,您可以将partition视为两个参数(类型为t -> Bool和type [t] )并返回类型([t], [t])

-> itself is a type-level operator; ->本身是一个类型级别的运算符; it takes two types as arguments and returns a function type. 它需要两种类型作为参数并返回一个函数类型。 It is right-associative, which means a -> (b -> c) and a -> b -> c are equivalent. 它是右关联的,这意味着a -> (b -> c)a -> b -> c是等价的。

No, insert is a function , so it can't be "of type t ". 不, insert是一个函数 ,所以它不能是“ t型”。 If it were of type t , it would be a value : 如果它是t类型,那么它将是一个

a :: Int
a = 5

Here a is of type Int . 这里a类型的 Int

As you can see from the function implementation, insert takes three arguments: 从函数实现中可以看出, insert三个参数:

insert a True (b,c) = ...

The arguments are a , True and (b, c) . 参数是aTrue(b, c)

So, the type of insert is exactly t -> Bool -> ([t],[t]) -> ([t],[t]) : 所以, insert的类型恰好是t -> Bool -> ([t],[t]) -> ([t],[t])

  1. it's a function (because of -> s) 这是一个功能(因为-> s)
  2. ...of one argument of some type t ... 某种类型的一个论点t
  3. ...and returns another function of type Bool -> ([t],[t]) -> ([t],[t]) ...并返回Bool -> ([t],[t]) -> ([t],[t])类型的另一个函数 Bool -> ([t],[t]) -> ([t],[t])
    1. ...which takes one argument of type Bool (and Bool only) ...取一个 Bool类型的参数 (仅限Bool
    2. ...and returns a function ([t],[t]) -> ([t],[t]) ...并返回一个函数([t],[t]) -> ([t],[t])
    3. (this should be one level of indentation deeper) ...which takes one argument of type ([t],[t]) (a tuple of two lists, each of which holds values of some type t ) (这应该是更深层次的缩进级别)...它接受一个类型的参数([t],[t]) (两个列表的元组,每个列表都包含某些类型的值t
    4. ...and returns, finally, a value of type ([t],[t]) ...并返回,最后,类型的 ([t],[t])

Now, this looks like a mess: functions returning other functions that return functions... But this can be simplified. 现在,这看起来像一团糟:函数返回其他返回函数的函数......但这可以简化。 You can think of insert as a function of three arguments: 您可以insert视为三个参数的函数:

  1. insert is this crazy function that returns other functions: type t -> Bool -> ([t],[t]) -> ([t],[t]) insert是这个返回其他函数的疯狂函数:type t -> Bool -> ([t],[t]) -> ([t],[t])
  2. insert 2 is of type Bool -> ([t],[t]) -> ([t],[t]) insert 2Bool -> ([t],[t]) -> ([t],[t])类型Bool -> ([t],[t]) -> ([t],[t])
  3. insert 2 True if of type ([t],[t]) -> ([t],[t]) insert 2 True如果类型为([t],[t]) -> ([t],[t])
  4. insert 2 True ([1], [2]) is of type ([t],[t]) insert 2 True ([1], [2])的类型为([t],[t])

BOOM! 繁荣! The last call actually returned a value, not a function! 最后一次调用实际上返回了一个值,而不是函数! And due to this, one can treat insert as a function of three arguments. 因此,可以将insert视为三个参数的函数。 This thing is called currying, and it's named after the same man after whom Haskell is named - Haskell Curry. 这个东西叫做currying,它是以Haskell命名的同一个人命名的--Haskell Curry。

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

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