6

我一直在学习 uncurrying 和在 haskell 中应用 $ 函数,但我仍然在将 uncurried 函数转换为不那么神秘的东西时遇到问题。

我得到的功能是

apple = map $ uncurry $ flip ($)

我意识到这需要一个元组列表并将元组中的相应函数应用于内部变量。所以我试图将其重写为

apple ls = foldr function _ ls
    where function (a,b) c = (uncurry b) (a,c)

我将 _ 的错误视为解析错误,我不知道要使用哪个起点。我需要使这种多态性,并且我意识到这很可能不会使它变得不那么神秘。有任何想法吗?他们将不胜感激

4

2 回答 2

7

苹果有类型

apple :: [(a, a->b)] -> [b]

我们可以将其重写为

apple ls = map (\(a, f) -> f a) ls

所以写这个foldr是非常可行的,

apple ls = foldr (\(a, f) rest -> f a : rest) [] ls

或者,我们可以将其重写为 pointfree

apple = foldr ( (:) . (uncurry . flip $ ($)) ) []

解析错误的原因是_“我不关心的变量”的特殊语法。这让你写的东西像

 foo _ _ _ _ a = a

并且不会得到关于重复变量的错误。基本上我们只是填写_了起始的空列表并修复function了它,以便它附加到c而不是试图将它应用到a.

如果我想以最清晰的方式写这个,那么原来的

apple = map . uncurry . flip $ ($)

相当不错。

于 2013-10-24T01:05:55.970 回答
1

理解的关键是消除复杂性。

因此,我建议您先处理单个元组。编写以下函数:

 tapp :: (a, a ->b) -> b

就 ($) 和flip和而言uncurry。(为了更容易,你可以先为一个元组做这件事(a -> b, a))。

接下来,让自己弄清楚 map 是如何工作的:如果你有一个 function f :: (a -> b),那么map fwill be a function [a] -> [b]。因此map tapp做你想要的。

您现在可以用它的定义替换tappin map (tapp)(这是引用透明的好处)。这应该带你回到你原来的表情。或多或少如此,因为,例如:

f $ g h

可以写

f (g h)

或者

(f . g) h
于 2013-10-24T11:30:55.253 回答