为什么在Haskell函数应用程序中使用逗号会导致不同的类型?
我在ghci中运行了这些haskell函数,然后得到了这些输出,但我不知道如何解释它。g(x,y)和g(x,y)之间的区别是什么,以及产量是如何变化的为什么在Haskell函数应用程序中使用逗号会导致不同的类型?,haskell,Haskell,我在ghci中运行了这些haskell函数,然后得到了这些输出,但我不知道如何解释它。g(x,y)和g(x,y)之间的区别是什么,以及产量是如何变化的 *Main> let j g (x, y) = g(x,y) *Main> :t j j :: ((a, b) -> t) -> (a, b) -> t *Main> let j g (x, y) = g(x y) *Main> :t j j :: (t1 -> t2) -> (t3 -
*Main> let j g (x, y) = g(x,y)
*Main> :t j
j :: ((a, b) -> t) -> (a, b) -> t
*Main> let j g (x, y) = g(x y)
*Main> :t j
j :: (t1 -> t2) -> (t3 -> t1, t3) -> t2
g(x,y)
和g(x,y)
之间有什么区别,以及它们是如何产生输出的
*Main> let j g (x, y) = g(x,y)
*Main> :t j
j :: ((a, b) -> t) -> (a, b) -> t
*Main> let j g (x, y) = g(x y)
*Main> :t j
j :: (t1 -> t2) -> (t3 -> t1, t3) -> t2
与编程语言的总量相比,Haskell有一种“不同寻常”的语法(与C、Java等非常常见的语言相比)来描述函数应用程序
f x
是一个函数应用程序,它具有f
函数和x
参数。括号不是必需的(与例如C、Java、C#等编程语言相比),但是可以包括括号。因此f(x)
被解释为f(x)
,由于(x)
只是x
,两者是等价的
考虑到这一点,如果我们看一下g(xy)
,我们会看到两个函数应用程序:xy
,和g(xy)
。在Java这样的编程语言中,这看起来像g(x(y))
<因此,code>g和x
都是功能(其中x
的“输出类型”应与g
的“输入类型”相同)。我们使用x
函数和y
参数执行函数应用,结果是使用g
函数的函数应用中的参数
Haskell也有元组。例如(4,2)
一个2元组(x,y)
也是一个2元组:x
是第一个元素,y
是第二个元素。如果我们这样写g(x,y)
,那么我们用g
函数和(x,y)
(2元组)参数执行函数应用程序。这意味着x
具有类型a
,y
具有类型b
,然后g
具有类型(a,b)->c
考虑到这一点,我们可以导出函数的签名,例如:
j g (x, y) = g (x,y)
我们在这里看到,j
有“两个”参数(在Haskell中,所有函数都有一个参数,该函数的结果取另一个参数),因此我们首先将函数的签名描述为:
j :: a -> b -> c
g :: a
(x, y) :: b
g (x, y) :: c
由于(x,y)
是一个元组,我们将(x,y)
的类型专门化为(d,e)
,这意味着签名更改为:
j :: a -> (d, e) -> c
g :: a
(x, y) :: b ~ (d, e)
g (x, y) :: c
x :: d
y :: e
(瓷砖~
代表两种类型相同的事实)
由于我们用(x,y)
作为参数调用g
,我们知道g
是一个函数。输入类型是参数(x,y)
,因此(d,e)
,而其结果类型是jg(x,y)
的结果类型,因此c
,因此我们推导出g
具有类型(d,e)->c
,这意味着:
j :: ((d, e) -> c) -> (d, e) -> c
g :: a ~ ((d, e) -> c)
(x, y) :: b ~ (d, e)
g (x, y) :: c
x :: d
y :: e
然后满足所有约束,因此j
的类型为:
j :: ((d, e) -> c) -> (d, e) -> c
我把推导j g(x,y)=g(x y)的类型留作练习。在Haskell中(与C派生语言不同),函数调用不会在函数后用括号表示。相反,Haskell将任意两个连续表达式视为函数应用程序,因此(xy)
读作“应用于参数y
的函数x
”
与C派生语言不同,Haskell对元组具有本机支持:(x,y)
读取“x后接y
的元组”
将这些结合在一起,Haskell将把g(x,y)
视为“应用于元组(x,y)的函数g
,这类似于它在类C语言中的读取方式。但是,这种相似性是误导性的:类C函数调用需要括号来表示函数调用,而在Haskell中,括号仅用于分隔元组
在您的另一个示例中,
g(xy)
读取“应用于(functionx
应用于参数y
)的结果的函数g
”。在类C语言中,xy
将是语法错误,但Haskell将其识别为函数应用程序。g(xy)
意味着x
是一个函数,首先使用x
函数和y
参数执行函数应用,然后将结果传递给g
。您好,您似乎是一个Haskell初学者。我强烈建议初学者在开始提问之前,先阅读完整的函数问题是否在LYAH中得到了回答。也请务必查看让j g(x,y)=(g x y)
@AJFarmar附议,但“完成”除外。。提问是学习的一个重要部分,即使在使用“教科书”时也是如此。但我同意喇嘛可能从阅读几章中受益。你能解释一下这个函数的类型吗*Main>let j g(x,y)=g(x y)*Main>:t j j::(t1->t2)->(t3->t1,t3)->t2与ML、Idris、Agda等相同。在事物的大格局中可能不常见,但远不是唯一的!在这种表达中很清楚。请描述类型签名:h f=foldr((:).f)[@LamaMadan:我建议你问一个新问题,因为这是一个新问题:)。