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-所有非平凡的一致类型系统都不允许有意义的事情。这是哥德尔不完全性定理的直接结果。