Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在Haskell函数应用程序中使用逗号会导致不同的类型?_Haskell - Fatal编程技术网

为什么在Haskell函数应用程序中使用逗号会导致不同的类型?

为什么在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 -

我在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 -> 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)
读取“应用于(function
x
应用于参数
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:我建议你问一个新问题,因为这是一个新问题:)。