【问题标题】:How can I declare the type of a function defined within a let如何声明在 let 中定义的函数的类型
【发布时间】:2014-07-08 02:33:17
【问题描述】:

我想写这样的东西:

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

但这给了我一个错误。因为它无法识别我正在尝试引用与声明中相同的“a”和“b”类型作为 f

我怎样才能明确地为内部指定正确的类型?

【问题讨论】:

  • 您需要扩展名ScopedTypeVariables,并且您可能还需要在您的签名中添加明确的forall a b c .。
  • 在这种特殊情况下,您实际上不需要内部类型签名,您甚至可以选择以f g = const . g(甚至f = (const .))的形式编写函数以获得相同的行为.你甚至不需要外部类型签名,GHC 用const . g 正确推断它。
  • @bheklilr,类型签名是很好的文档。如果有问题的程序员认为有一个有助于澄清事情,那么这是一个很好的理由加入。
  • @dfeuer 当然,我总是将类型签名放在代码中的顶级函数上,但我的意思是,编译此代码根本不需要类型签名。 ScopedTypeVariables 是不必要的,因为编译器可以从定义中完全推断出类型。

标签: haskell typechecking nested-function


【解决方案1】:

您需要扩展名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

【讨论】:

  • @luqui 谢谢你,我真的不知道为什么有必要!
【解决方案2】:

这样做的一种方法是通过在内部设置 g 参数来绑定外部和内部类型,就像这样......

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    相关资源
    最近更新 更多