Haskell:Lambda 函数 - 错误 - 逃脱其范围

标签 haskell lambda

我定义了以下模块:

module ComplexCompose where

isEven x =
 if x `rem` 2 == 0 then
  (True, "Is Even")
 else
  (False, "Is Odd")


negateIt x = ( not x, "negated")



composer x =
 (c, b ++ ", " ++ d) where (a,b) = isEven x
                           (c,d) = negateIt a

对 Composer 进行以下修改可以正常工作:

composerV1 x f g =
 (c, b ++ ", " ++ d) where (a,b) = f x
                           (c,d) = g a

我想让composer函数返回一个由f和g组成的lamda。我试过这个:

composerV2 f g =
     \x -> (c, b ++ ", " ++ d) where (a,b) = f x
                                     (c,d) = g a

这不起作用。这个版本有什么问题吗?

编译器输出:

 • Couldn't match expected type ‘t0 -> (t5, t4)’
                  with actual type ‘t3’
        because type variables ‘t4’, ‘t5’ would escape their scope
      These (rigid, skolem) type variables are bound by
        the inferred type of
        a :: t5
        b :: t4
        at complex-compose.hs:27:34-44
    • In the expression: f x
      In a pattern binding: (a, b) = f x
      In an equation for ‘c4’:
          c4 f g
            = \ x -> (c, b ++ ", " ++ d)
            where
                (a, b) = f x
                (c, d) = g a
    • Relevant bindings include
        a :: t5 (bound at complex-compose.hs:27:35)
        b :: t4 (bound at complex-compose.hs:27:37)
        f :: t3 (bound at complex-compose.hs:26:4)
        c4 :: t3 -> (t2 -> (t1, [Char])) -> t -> (t1, [Char])
          (bound at complex-compose.hs:26:1)

顺便说一句,以下简单的函数可以工作:

fn f g = \x = g(f x)

最佳答案

如果我不在左侧写下 x

composerV2 会为我进行类型检查:

composerV2 f g x =
     (c, b ++ ", " ++ d) where (a,b) = f x
                               (c,d) = g a

问题在于,在 where 子句中,标识符 x 实际上不在范围内。错误消息有点令人困惑,但如果添加类型签名,就会变得精确,无论如何,这是一个很好的做法。

或者,您也可以使用 let 绑定(bind)。

请注意,composerV2 f g = let ... in\x -> ...composerV2 f g x = ... 在语义上是相同的,因为您可以部分应用第二个版本。

编辑:使用 let 绑定(bind)的版本如下所示:

composerV2' f g = \x ->
  let (a,b) = f x
      (c,d) = g a
  in (c, b ++ ", " ++ d)

关于Haskell:Lambda 函数 - 错误 - 逃脱其范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47747184/

相关文章:

haskell - 选择 AMI 来部署 haskell 应用程序?

c# - 如果索引已存在,如何根据索引加入列表并合并成员

haskell 多态性和列表

通过递归检查尾部来迭代列表的性能

string - SplitAt 3 然后继续 split

java - 使用 Java lambda 对 SQL 中的对象进行分组和求和?

c++ - 我意识到这是错误的,但我无法删除它

c++ - 用于构造 std::thread 时,仿函数和 lambda 之间有什么区别

c# - 检测 LambdaExpression 是否用于对象的属性

haskell - 由于 "fold"的功能不足以编写带有缩进的树形 pretty-print ,那么什么是高阶组合器呢?