我将如何使用函数组合(。)/应用程序($)运算符来重写此表达式? [英] How would I re-write this expression using the function composition (.) /application ($) operators?
问题描述
我一直在努力去掌握Haskell中的(。)
和($)
运算符。我相信我理解了它们之间的差异,但我仍然很难成功用这些运算符替换表达式中的括号。
例如,如果我有表达式
print(show (以5 [1..10]))
我知道如何使用(。)
和($)
操作符
打印。显示 。 5 $ [1..10]
但是,如果我有像
print(show(take(snd(1,5))[1..10]))
我可以将这个简化为最远的是
<$ c $打印。显示 。 (snd(1,5))$ [1..10]
无论我尝试什么我似乎无法用($)
或(。)
运算符替换这些内部圆括号,并让它成功编译。据我所知,大多数Haskellers通常在括号中使用($)
和(。)
运算符,所以我努力尝试也要遵循这种风格。如果有人可以指出我如何在不使用括号的情况下重写上述表达式,我认为这会帮助我更成功地使用这些操作符。谢谢。
您的重写...
打印。显示 。 (snd(1,5))$ [1..10]
...是就可读性而言,它很好。以下建议实际上会使事情变得比必要更复杂;如你所说,知道这样的事情是可能的,可以更好地理解 适用于 ...让我们暂时关注一下。如果你试图在没有表达式的其余部分的情况下消除括号,那么你可能会得到...... 要重建原始函数,我们需要将它应用于 ...但由于我们避免括号,所以我们需要额外的欺骗。有两种即时选项。第一个是通过 就像 ...接受函数并将其应用于 在这一点上,我们可以用与原始版本相同的方式完成表达式: 另一种选择是写入整个函数pointfree(也就是没有明确地写出参数)。要做到这一点,让我们回到...... ......并且暂时保留一对: ...取一对和一个列表并返回一个列表。但是,我们也可以将此类型读为: ...也就是说,我们有一个函数需要一对并返回一个函数。如果我们使用 ...即, ...和... 利用我们手中的无点函数,我们可以根据自己的喜好提供参数 - - 例如,像这样... ...或者这个... ...或者甚至是... ...或者,对于不那么古怪的事情: 确实有很多选择 - 他们都会密切合作,展示你最初的改写是多么的好! I've been trying very hard to grasp the For example, if I have the expression I understand how to rewrite it using the However, if I had something like The furthest I can simplify this down to is No matter what I try I can not seem to replace those inner parenthesis with the Your rewrite... ... is as good as it gets in terms of readability. The following suggestions will in fact make it more convoluted than necessary; still, knowing such things are possible can, as you say, bring a better appreciation of how The first function which is applied to ... so let's focus on it for a moment. If you were trying to eliminate parentheses there without the rest of the expression, you might end up with... To reconstruct the original function, we need to apply that to ... but since we are avoiding parentheses, we need extra trickery. There are two immediate options. The first one is passing the list to the function with a Just like ... that takes a function and applies it to At this point, we can complete the expression in the same manner of your original version: The other option is writing the whole function pointfree (that is, without explictly writing the arguments). To do that, let's get back to... ... and leave out the pair for a moment: ... that takes a pair and a list and gives back a list. We can, however, also read this type as: ... that is, we have a function that takes a pair and returns a function. If we compose some function ... namely, ... and... With the pointfree function in our hands, we can supply the arguments in whichever way we feel like -- for instance, like this... ... or this... ... or even this... ... or, for something less bizarre: There are indeed many alternatives -- and they all conspire to show how nice your original rewrite was in the first place! 这篇关于我将如何使用函数组合(。)/应用程序($)运算符来重写此表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!($)
和(。)$ c $工作。
[1..10]
的第一个函数是...
take(snd(1,5))
take。 snd $(1,5)
[1..10]
。这样做的一种自然方式就是......
(take。snd $(1,5))[1 .. 10]
($)
部分将列表传递给函数:
($ [1..10])。采取。 snd $(1,5)
(* 2)
是一个函数,它将一个数字乘以二,($ [1..10])
是一个函数...
GHCi> :t($ [1..10])
($ [1..10])::(Num t,Enum t)=> ([t]→b)→> b
[1。 0.10
。 (是的,我刚刚添加了一对括号;但是,它们并未真正用于分组 - ($ [1..10])
只是替代方法 flip($)[1..10]
的语法 - 所以我说他们不计算:))
print。显示 。 ($ [1..10])。采取。 snd $(1,5)
take。 snd $(1,5)
take。 snd
取。 snd
是一个函数...
GHCi> :拿。 snd
取。 snd ::(a1,Int) - > [a] - > [a]
take。 snd ::(a1,Int) - > ([a] - > [a])
take编写一些函数
以便我们得到 foo
。 snd foo。采取。 snd
, foo
将应用于由 take生成的函数。 SND
。事实上,当我们在上面使用($ [1..10])
时,我们已经做到了。除了提供参数之外,我们可以用函数做的另一件事是组合它们。我们确实有一个操作员来编写函数......
((print。show)。)。采取。 snd
(。)
。括号中的奇怪表达式是(。)
的一部分,就像我们用于($)
之前,除了这是一个左侧部分,这是一个正确的部分。由于运算符优先级诡计,需要一对额外的括号;同样令人不满意的选择包括... ...
(print。)。 (显示 。) 。采取。 snd
(。)打印。 (。) 显示 。采取。 snd
$ b $
(((print。show)。)。take。snd)(1, 5)[1..10]
($ [1..10])。 ((print。show)。)。采取。 snd $(1,5)
($ [1..10])。 ($(1,5))$((print。show)。)。采取。 snd
let f =((print。show)。)。采取。 snd in f(1,5)[1..10]
(.)
and ($)
operators in Haskell. I believe I understand the differences between them well enough, but I am still having a hard time successfully replacing the parentheses in my expressions with these operators. print(show(take 5 [1..10]))
(.)
and ($)
operatorsprint . show . take 5 $ [1..10]
print (show (take (snd (1,5)) [1..10]))
print . show . take (snd (1,5)) $ [1..10]
($)
or (.)
operator and have it successfully compile. I understand that most Haskellers typically use the ($)
and (.)
operators over parentheses so I am trying really hard to follow that style as well. If someone could point out how I could rewrite that expression above without using parenthesis I think it would help me use those operators with much more success. Thanks.print . show . take (snd (1,5)) $ [1..10]
($)
and (.)
work. [1..10]
is...take (snd (1,5))
take . snd $ (1,5)
[1..10]
. A natural way of doing so would be...(take . snd $ (1,5)) [1..10]
($)
section:($ [1..10]) . take . snd $ (1,5)
(* 2)
is a function that takes a number and multiplies it by two, ($ [1..10])
is a function...GHCi> :t ($ [1..10])
($ [1..10]) :: (Num t, Enum t) => ([t] -> b) -> b
[1..10]
. (And yes, I have just added a pair of parentheses; however, they are not really being used for grouping -- ($ [1..10])
is just alternative syntax for flip ($) [1..10]
-- so I say they don't count :))print . show . ($ [1..10]) . take . snd $ (1,5)
take . snd $ (1,5)
take . snd
take . snd
is a function...GHCi> :t take . snd
take . snd :: (a1, Int) -> [a] -> [a]
take . snd :: (a1, Int) -> ([a] -> [a])
foo
with take . snd
so that we get foo . take . snd
, foo
will be applied to the function produced by take . snd
. In fact, we have done just that when we used ($ [1..10])
just above. Besides supplying argments, another thing we can do with functions is composing them. And we do have an operator for composing functions...((print . show) .) . take . snd
(.)
. The weird expression within the parentheses is a section of (.)
, just like the one we used for ($)
before, except that this is a left section, and that was a right section. Due to operator precedence shenanigans an extra pair of parentheses is necessary; equally unsatisfactory alternatives include...(print .) . (show .) . take . snd
(.) print . (.) show . take . snd
(((print . show) .) . take . snd) (1,5) [1..10]
($ [1..10]) . ((print . show) .) . take . snd $ (1,5)
($ [1..10]) . ($ (1,5)) $ ((print . show) .) . take . snd
let f = ((print . show) .) . take . snd in f (1,5) [1..10]