Haskell 的类型签名 u f=f.f 比我想要的强
Haskell's type signature of u f=f.f is stronger than I would like
我写了下面这个简单的函数
u f=f.f
根据 ghci
这具有
的类型签名
u :: (b -> b) -> b -> b
但是那个类型签名太严格了。 Haskell 强制我们的输入为 (b -> b)
类型,但不一定需要如此。例如,函数 (:[])
的类型签名为
(:[]) :: a -> [a]
它不是 (b -> b)
的形式(除非您允许无限类型),因此无法传递给 u
。但是你可以用它自己组合 (:[])
。
g=(:[]).(:[])
这有效并且具有类型
(:[]).(:[]) :: a -> [[a]]
所以我原则上应该能够将其传递给 u
。
我尝试自己编写一个新的类型签名来替换生成的签名,但我想不出一种方法来表达函数的要求。我总是想出与编译器提供的相同类型签名。我们是否可以提供类型签名来削弱 u
以便可以将 (:[])
之类的函数传递给它?
有很多不同的函数可以针对特定情况执行此操作,但 none 通常都可以。
u1 :: (forall a. a -> f a) -> b -> f (f b)
u2 :: (forall a. f a -> a) -> f (f b) -> b
还有无限可能。但是函数
u f x = f (f x)
没有 Haskell 中最通用的类型,当 RankNTypes
正在播放时。正如 pigworker 所指出的,有些类型系统可以为 u
提供您想要的基本类型,但它们将类型系统扩展的方向与 Haskell 设计人员所关注的方向截然不同。
我写了下面这个简单的函数
u f=f.f
根据 ghci
这具有
u :: (b -> b) -> b -> b
但是那个类型签名太严格了。 Haskell 强制我们的输入为 (b -> b)
类型,但不一定需要如此。例如,函数 (:[])
的类型签名为
(:[]) :: a -> [a]
它不是 (b -> b)
的形式(除非您允许无限类型),因此无法传递给 u
。但是你可以用它自己组合 (:[])
。
g=(:[]).(:[])
这有效并且具有类型
(:[]).(:[]) :: a -> [[a]]
所以我原则上应该能够将其传递给 u
。
我尝试自己编写一个新的类型签名来替换生成的签名,但我想不出一种方法来表达函数的要求。我总是想出与编译器提供的相同类型签名。我们是否可以提供类型签名来削弱 u
以便可以将 (:[])
之类的函数传递给它?
有很多不同的函数可以针对特定情况执行此操作,但 none 通常都可以。
u1 :: (forall a. a -> f a) -> b -> f (f b)
u2 :: (forall a. f a -> a) -> f (f b) -> b
还有无限可能。但是函数
u f x = f (f x)
没有 Haskell 中最通用的类型,当 RankNTypes
正在播放时。正如 pigworker 所指出的,有些类型系统可以为 u
提供您想要的基本类型,但它们将类型系统扩展的方向与 Haskell 设计人员所关注的方向截然不同。