繁体   English   中英

了解功能的类型

[英]Understanding the types of 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)

从我有限的知识,我认为插入功能:

  • insert是t类型,它接受两个参数bool和两个类型为t的列表之一,并返回两个t类型列表的元组。

  • partition是类型为t的元组,它返回一个bool,它接受一个类型为t的列表作为参数,并返回两个类型为t的列表的元组。

这是正确的思考方式还是我弄错了? 我一直在关注一些教程,这是我到目前为止所理解的。

insertt类型,它接受Bool两个参数和两个类型为t列表中的一个元组,并返回两个类型为t列表的元组。

首先,它注意到在Haskell每个函数带一个参数是非常重要的。 确实

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

是一种简短紧凑的形式:

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

事实上,上述内容仍然不是很冗长,规范形式如下:

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

但上面当然不是很易读,所以让我们坚持第二种形式。

Haskell中的每个函数只需要一个参数。 什么这里发生的是应用参数有一定作用的结果 ,产生了新的功能。

因此,如果我们生成一个表达式insert x ,我们构造了一个Bool -> (([t], [t]) -> ([t], [t]))类型的函数。

非正式地 ,人们确实有时会说“ 函数需要n个参数 ”。 但重要的是要记住这一点。

其次你忘了t 我们可以非正式地说insert三个参数,一个是t类型的值,一个boolean(类型为Bool ),一个带有两个t s列表的2元组。 它将返回两个t的两个元组列表。 根据BoolTrue还是False它会在两个列表中添加给定值之一。

例如:

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是类型为t的元组,它返回一个bool ,它接受一个类型为t的列表作为参数,并返回两个类型为t列表的元组。

不,这里的参数有一个函数类型(t -> Bool) 实际上,在Haskell中,您可以将函数作为参数传递。

非正式地,我们可以说partition采用“ 谓词 ”(将值映射到Bool的函数)和t s列表,并返回带有两个t s列表的2元组。 根据谓词是否适用于列表中的值,这些值将在2元组的第一个或第二个列表中排序。

例如:

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])

不,类型完全如图所示:

insert有类型t -> Bool -> ([t], [t]) -> ([t], [t]) ,这意味着它是一个函数,它将t类型的值作为参数并返回一个函数Bool -> ([t], [t]) -> ([t], [t])类型Bool -> ([t], [t]) -> ([t], [t]) 非正式地,您可以insert视为一个带有3个参数的函数:一个是t类型,一个是Bool类型,另一个是类型([t], [t]) ,并返回另一个类型的值([t], [t])

partition是一个函数,它接受另一个函数(类型为t -> Bool )作为参数,并返回一个类型为[t] -> ([t],[t]) 非正式地,您可以将partition视为两个参数(类型为t -> Bool和type [t] )并返回类型([t], [t])

->本身是一个类型级别的运算符; 它需要两种类型作为参数并返回一个函数类型。 它是右关联的,这意味着a -> (b -> c)a -> b -> c是等价的。

不, insert是一个函数 ,所以它不能是“ t型”。 如果它是t类型,那么它将是一个

a :: Int
a = 5

这里a类型的 Int

从函数实现中可以看出, insert三个参数:

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

参数是aTrue(b, c)

所以, insert的类型恰好是t -> Bool -> ([t],[t]) -> ([t],[t])

  1. 这是一个功能(因为-> s)
  2. ... 某种类型的一个论点t
  3. ...并返回Bool -> ([t],[t]) -> ([t],[t])类型的另一个函数 Bool -> ([t],[t]) -> ([t],[t])
    1. ...取一个 Bool类型的参数 (仅限Bool
    2. ...并返回一个函数([t],[t]) -> ([t],[t])
    3. (这应该是更深层次的缩进级别)...它接受一个类型的参数([t],[t]) (两个列表的元组,每个列表都包含某些类型的值t
    4. ...并返回,最后,类型的 ([t],[t])

现在,这看起来像一团糟:函数返回其他返回函数的函数......但这可以简化。 您可以insert视为三个参数的函数:

  1. insert是这个返回其他函数的疯狂函数:type t -> Bool -> ([t],[t]) -> ([t],[t])
  2. insert 2Bool -> ([t],[t]) -> ([t],[t])类型Bool -> ([t],[t]) -> ([t],[t])
  3. insert 2 True如果类型为([t],[t]) -> ([t],[t])
  4. insert 2 True ([1], [2])的类型为([t],[t])

繁荣! 最后一次调用实际上返回了一个值,而不是函数! 因此,可以将insert视为三个参数的函数。 这个东西叫做currying,它是以Haskell命名的同一个人命名的--Haskell Curry。

暂无
暂无

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

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