在lambda表达式中的Haskell类型签名

16

假设我在程序中有一个lambda表达式,如下:

\x -> f $ x + 1

我希望通过类型安全来指定x必须是整数。例如:

-- WARNING: bad code
\x::Int -> f $ x + 1

2
(\x -> f $ (x::Int) + 1) - Adam Gordon Bell
你所说的“类型安全”具体是什么意思?对于 x 的推断类型(Num a => a)相比于 Int,有哪些方面是不够安全的呢? - sepp2k
2
@sepp2k 我正在编写的实际代码确实显示了x,而且很多东西都可以显示,但我只想让这个lambda在x是某种类型(比如Int)时编译。问题中的代码不是实际代码,只是提问的最短方式。 - Marton Trencseni
2个回答

17
你可以仅仅写 \x -> f $ (x::Int) + 1来替换它。或者更易读的方式是 \x -> f (x + 1 :: Int)。需要注意的是,类型签名通常会包括它们左侧的所有内容,尽可能远离左侧,并且与lambda表达式相反,lambda表达式扩展到右侧。

顺便提一下,GHC扩展 ScopedTypeVariables 允许在模式中直接编写签名,这将允许 \(x::Int) -> f $ x + 1。但是该扩展还添加了其他您可能不想担心的东西;我不会仅为了语法上的美感而打开它。


1
谢谢,非常好的答案。实际上我正在使用这个在Template Haskell中,关于第二个选项,GHC 7.4.1说“模板Haskell尚未处理模式中的类型签名”。 - Marton Trencseni
2
哈哈,是啊。TH 不理解 GHC 支持的许多语法扩展,唉。 - C. A. McCann

13
我想补充一下C.A.McCann的回答,指出您不需要使用ScopedTypeVariables。即使您从未使用过该变量,仍然可以执行以下操作:
\x -> let _ = (x :: T) in someExpressionThatDoesNotUseX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接