我定义了以下模块:
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
以下对作曲家的修改工作正常:
composerV1 x f g =
(c, b ++ ", " ++ d) where (a,b) = f x
(c,d) = g a
我想让作曲家函数返回一个组成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)
答案 0 :(得分:0)
composerV2
, x
会为我打字:
composerV2 f g x =
(c, b ++ ", " ++ d) where (a,b) = f x
(c,d) = g a
问题是在where
子句中,标识符x
实际上并不在范围内。错误消息有点令人困惑,但如果添加类型签名则会变得精确,这无论如何都是很好的做法。
或者,您可以使用let
绑定。
请注意,composerV2 f g = let ... in \x -> ...
和composerV2 f g x = ...
在语义上是相同的,因为您可以部分应用第二个版本。
编辑:使用let
绑定的版本如下所示:
composerV2' f g = \x ->
let (a,b) = f x
(c,d) = g a
in (c, b ++ ", " ++ d)