我定义了以下模块:
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/