实现咖喱功能
我目前正在阅读由Graham Hutton编写的“haskell编程”,并且刚刚达到了咖喱和功能组合。在练习部分中,有一项任务是从零开始实施咖喱功能,这已经存在于前奏中模块。实现咖喱功能
这里是我的实现,但它不是working.Can人解释(我是新来的函数式编程),为什么它不工作
my_curry :: ((a ,b) -> c) -> (a -> b -> c)
my_curry origFunc = origFunc.combine
where
combine e f = (e, f)
这里的错误[添加]
[1 of 1] Compiling Main (higher_order.hs, interpreted)
higher_order.hs:92:30:
Couldn't match type `t0 -> (a, t0)' with `(a, b)'
Expected type: a -> (a, b)
Actual type: a -> t0 -> (a, t0)
In the second argument of `(.)', namely `combine'
In the expression: origFunc . combine
In an equation for `my_curry':
my_curry origFunc
= origFunc . combine
where
combine e f = (e, f)
问题是.
是为了拿单参数的函数,并将它们粘合在一起,
在这种情况下combine
的类型为a -> b -> (a, b)
。所以它的第一个参数是a
,它的返回类型是b -> (a, b)
(记得->
组右侧)。所以.
有型
(.) :: (b -> c) -> (a -> b) -> a -> c
由于combine
是第二个参数Haskell是要统一像
(.).a ~ combine.a
(.).b ~ (combine.b -> (combine.a, combine.b))
我使用foo.bar
.
S型变量来自定义指的是类型变量bar
foo
。接下来我们将其作为类型(a, b) -> c
填入origFunc
。现在,当我们尝试将其合并到.
时,我们得到了
(.).b ~ my_curry.(a, b)
(.).c ~ my_curry.c
但是等等! b
不能同时为(a, b)
和b -> (a, b)
,因此类型错误。
相反,我们有两个选择,我们可以创建一个新的类型的组成
(..) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
f .. g = \a b -> f (g a b)
注意如何让g
取两个参数,和你的功能变得
my_curry origFunc = combine .. origFunc
,或者我们可以只使用currying
my_curry origFunc x y = origFunc (x, y)
另一种做这种构图的方法是'my_curry origFunc =(origFunc。)。 combine'。 – 2014-08-29 01:40:11
@JohnL当然,我不确定这对Haskell初学者是否合适 – jozefg 2014-08-29 01:43:29
jozefg的答案解释了为什么你的代码不起作用,我想我会为你提供一个相当直接的实现。
请注意my_curry
的函数签名是((a, b) -> c) -> (a -> b -> c)
。它接受一个函数,并返回一个函数作为结果。我们可以用一个lambda表达式轻易俘获的“返回一个函数”的概念:
my_curry func = \x y -> func (x, y)
所有这些代码确实是发生在左侧等号的单一功能,并在返回一个新功能右侧。它返回的函数一次只取一个参数,对它们进行元组化,并将它们传递给我们传入的任何函数。
我们可以看到的另一种方法是删除类型签名中的括号。由于类型签名中的箭头是右关联的,因此my_curry
的类型也可以写为((a, b) -> c) -> a -> b -> c
。在这种形式下,我们可以看到我们也可以实现my_curry
作为一个函数,它有三个参数:输入函数,以及x和y来元组化并通过该函数发送。因此,写功能的另一个有效办法是
my_curry func x y = func (x, y)
-1 - “不工作”没有意义。澄清你的意思:1)代码是否编译? (如果不是,你为什么不发布你得到的错误?)2)程序是否返回意外的结果? (你为什么不公布你得到的结果和你期望的结果?)3)程序是否以其他方式崩溃或失败? (你为什么不描述它?)。 – Bakuriu 2014-08-28 18:05:24
只需注意,如果您对代码的错误信息(即错误消息是什么)给出了更多详细信息,您将来可以更迅速地得到答案。否则,我们都必须弄清楚什么是错的,然后修复它,但这并不总是可行的。 – jozefg 2014-08-28 18:08:06