如何声明let中定义的函数的类型

时间:2014-05-20 01:05:07

标签: haskell typechecking nested-function

我想写一些类似的东西:

f :: (a -> b) -> a -> c -> b
f g =
   let inner :: a -> c -> b
       inner x y = g x
   in inner

但是这给了我一个错误。因为它没有意识到我试图引用同一个" a"和" b"声明中的类型为f

如何明确为内部提供正确的类型?

2 个答案:

答案 0 :(得分:17)

您需要扩展程序ScopedTypeVariables。您还需要在签名中添加一个显式forall a b c .,它表示绑定整个定义范围的变量。

{-# LANGUAGE ScopedTypeVariables #-}

f :: forall a b c . (a -> b) -> a -> c -> b
f g =
   let inner :: a -> c -> b
       inner x y = g x
   in inner

答案 1 :(得分:5)

执行此操作的一种方法是通过在内部创建g参数来绑定外部和内部类型,就像这样......

f g =
   let inner :: (a->b)->a -> c -> b
       inner g x y = g x
   in inner g

这确实稍微改变了你的结构......并且可能否定了首先有内部let的原因,但在很多情况下(取决于更大的程序)这可能会有所帮助。