[英]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的列表的元组。
这是正确的思考方式还是我弄错了? 我一直在关注一些教程,这是我到目前为止所理解的。
insert
是t
类型,它接受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
的两个元组列表。 根据Bool
是True
还是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) = ...
参数是a
, True
和(b, c)
。
所以, insert
的类型恰好是t -> Bool -> ([t],[t]) -> ([t],[t])
:
->
s) t
Bool -> ([t],[t]) -> ([t],[t])
类型的另一个函数 Bool -> ([t],[t]) -> ([t],[t])
Bool
类型的参数 (仅限Bool
) ([t],[t]) -> ([t],[t])
([t],[t])
(两个列表的元组,每个列表都包含某些类型的值t
) ([t],[t])
现在,这看起来像一团糟:函数返回其他返回函数的函数......但这可以简化。 您可以insert
视为三个参数的函数:
insert
是这个返回其他函数的疯狂函数:type t -> Bool -> ([t],[t]) -> ([t],[t])
insert 2
是Bool -> ([t],[t]) -> ([t],[t])
类型Bool -> ([t],[t]) -> ([t],[t])
insert 2 True
如果类型为([t],[t]) -> ([t],[t])
insert 2 True ([1], [2])
的类型为([t],[t])
繁荣! 最后一次调用实际上返回了一个值,而不是函数! 因此,可以将insert
视为三个参数的函数。 这个东西叫做currying,它是以Haskell命名的同一个人命名的--Haskell Curry。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.