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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.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 哈斯克尔';u f=f.f的s型签名比我想要的更强_Haskell_Types_Functional Programming_Type Signature - Fatal编程技术网

Haskell 哈斯克尔';u f=f.f的s型签名比我想要的更强

Haskell 哈斯克尔';u f=f.f的s型签名比我想要的更强,haskell,types,functional-programming,type-signature,Haskell,Types,Functional Programming,Type Signature,我编写了以下简单函数 u f=f.f u f x = f (f x) 根据ghci的规定,其类型签名为 u :: (b -> b) -> b -> b 但是,该类型签名过于严格。Haskell强制要求我们的输入类型为(b->b),而不需要这样做。例如,函数(:[])的类型签名为 (:[]) :: a -> [a] 它不是(b->b)(除非您允许无限类型),因此不能传递给u。但是,您可以自己编写(:[]) g=(:[]).(:[]) 这是有效的,并且具有 (:[]

我编写了以下简单函数

u f=f.f
u f x = f (f x)
根据
ghci
的规定,其类型签名为

u :: (b -> b) -> b -> b
但是,该类型签名过于严格。Haskell强制要求我们的输入类型为
(b->b)
,而不需要这样做。例如,函数
(:[])
的类型签名为

(:[]) :: a -> [a]
它不是
(b->b)
(除非您允许无限类型),因此不能传递给
u
。但是,您可以自己编写
(:[])

g=(:[]).(:[])
这是有效的,并且具有

(:[]).(:[]) :: a -> [[a]]
因此,原则上,我应该能够将其传递给
u


我试图自己编写一个新的类型签名来替换生成的签名,但我想不出一种表达函数需求的方法。我总是使用编译器提供的相同类型签名。我们是否可以提供类型签名来削弱
u
,以便将
(:[])
之类的函数传递给它

有很多不同的函数可以在特定情况下实现这一点,但没有一个能在一般情况下起作用

u1 :: (forall a. a -> f a) -> b -> f (f b)
u2 :: (forall a. f a -> a) -> f (f b) -> b
还有无限多的可能性。但是功能

u f=f.f
u f x = f (f x)

当使用
RankNTypes
时,Haskell中没有最通用的类型。正如pigworker所指出的,有一些类型系统可以为
u
提供您想要的原则类型,但它们在一个与Haskell设计人员关注的方向截然不同的方向上进行类型系统扩展。

您的示例并不等同于
u f=f。f
。在
g=(:[])。(:[])
中,每个
(:[])
都有不同的类型。在
uf=f中。f
,每个
f
必须具有相同的类型。这也是问题没有解决方案的原因。只有一个
f
,它可能只有一种类型。在
(:[])中的两个
(:[])
。(:[])
是不同的函数。他们有不同的类型。这是一个很好的问题。想想看,
RankNTypes
。什么时候多态函数是可组合的?
让u:(对于所有a.a->f a)->b->f(f b);u f=f。f
交叉口类型的粉丝(我不是,但我知道一些)可能会有所不同。@pigworker,如果我们有这些交叉口,会是什么样子?为交叉口编写
&
((a->b)和(b->c))->(a->c)
。啊,那么解释就是“哈斯克尔不允许有意义的事情”,一个忏悔的注释是合适的。@pigworker-所有非平凡的一致类型系统都不允许有意义的事情。这是哥德尔不完全性定理的直接结果。