English 中文(简体)
Haskell无点
原标题:Point-free in Haskell

我有这一守则,我想说是没有意义的;

(k t-> chr$ a + flip mod 26 (ord k + ord t -2*a)>

我如何这样做?

还有,除了“关于这种友好的思考”外,还有其他一些自由风格的一般规则?

最佳回答

改变职能

func x y z = (some expression in x, y and z)

作为无点形式,我通常努力遵循对最后参数<代码>/代码>所做的规定,并写上这一功能。

func x y z = (some function pipeline built using x and y) z

然后,我可以取消<代码>z,以获得

func x y = (some function pipeline built using x and y)

然后,再重提“y”和“x”程序,应以无记名形式填入。 在这一进程中承认的重要转变是:

    f z = foo $ bar z    -- or f z = foo (bar z)
<=> f z = foo . bar $ z
<=> f   = foo . bar

还必须记住,通过部分评价,你可以“打破”最后一项职能论点:

foo $ bar x y == foo . bar x $ y    -- foo applied to ((bar x) applied to y)

为您的具体职能,应考虑<代码>k和t的流量。 接着:

  1. Apply ord to each of them
  2. Add the results
  3. Subtract 2*a
  4. Take the result mod 26
  5. Add a
  6. Apply chr

因此,作为第一次简化尝试,我们发现:

func k t = chr . (+a) . (`mod` 26) . subtract (2*a) $ ord k + ord t

请注意,您可避免<代码>flip。 通过使用<代码>mod的一节,以及使用<代码>-的章节,在Haskell有<代码>后继功能(这些功能与书写负数的辛醇/编码相冲突:<代码>(-2)<><<>>>>>>>>>> > /代码> 和与<编码>第2条/代码”相同的编号)。

在这项职能中,<代码>ord k + ord t是使用的优秀候选人。 数据。 这一有用的集成器让我们取而代之的是ord k + ord t,其功能适用于kt:

func k t = chr . (+a) . (`mod` 26) . subtract (2*a) $ ((+) `on` ord) k t

我们现在非常接近于

func k t = (function pipeline) k t

因此

func = (function pipeline)

不幸的是,Haskell在形成具有一系列非正常职能的双轨功能时,是一种微不足道的症状,但也有一小trick(我看,我能否找到一个很好的参考)。

import Data.Function (on)

func = ((chr . (+a) . (`mod` 26) . subtract (2*a)) .) . ((+) `on` ord)

几乎是一根绝无点功能的管道,但这种粗.的堆积除外。 http://www.reddit.com/r/programming/comments/a9tb2/secret_haskell_operators/“rel=“noreferer”>on this page, 即:

import Data.Function (on)

(.:) = (.).(.)

func = (chr . (+a) . (`mod` 26) . subtract (2*a)) .: ((+) `on` ord)

为进一步说明这一点,你可以增加一些助手职能,将信“带”;-> Int换算为Caesar cipher。 例如:letter ToInt = subtract a 或d

问题回答

还有,除了“关于这种友好的思考”外,还有其他一些自由风格的一般规则?

您可以永远使用Mlambdabot的“pl”工具(要么在自由条件下使用斜线,要么使用。 您的法典复文如下:

(chr . (a +) . flip mod 26) . flip flip f (2 *a) . ((-) . (d) . (+) 或d.

如果你问我,那确实是一个改进。

无疑,将表达变成无点风格的trick。 我不敢声称是专家,但这里有些ti。

首先,你想在表达的最正确术语中孤立功能论点。 您的主要工具是flip,使用规则:

f a b ==> flip f b a
f (g a) ==> f $ g a

<代码>fg为功能,a为表示。 开始:

(k t -> chr $ a + flip mod 26 (ord k + ord t -2*a))
-- replace parens with ($)
(k t -> chr $ (a +) . flip mod 26 $ ord k + ord t - 2*a)
-- prefix and flip (-)
(k t -> chr $ (a +) . flip mod 26 $ flip (-) (2*a) $ ord k + ord t)
-- prefix (+)
(k t -> chr $ (a +) . flip mod 26 $ flip (-) (2*a) $ (+) (ord k) (ord t))

现在,我们需要从正确的手头上获得<代码>t。 为此,采用以下规则:

f (g a) ==> (f . g) a

因此:

-- pull the t out on the rhs
(k t -> chr $ (a +) . flip mod 26 $ flip (-) (2*a) $ ((+) (ord k) . ord) t)
-- flip (.) (using a section)
(k t -> chr $ (a +) . flip mod 26 $ flip (-) (2*a) $ ((. ord) $ (+) (ord k)) t)
-- pull the k out
(k t -> chr $ (a +) . flip mod 26 $ flip (-) (2*a) $ ((. ord) . ((+) . ord)) k t)

现在,我们需要把所有东西都放在<代码>k和t的左边,使之成为一个大功能术语,这样我们就能够表达<代码>(k t -> fk t)。 这里的情况是,事情有点思维。 首先,我们注意到,所有截至最后<代码><>$/code>的术语都是以单一理由行事的,因此我们能够组成:

(k t -> chr . (a +) . flip mod 26 . flip (-) (2*a) $ ((. ord) . ((+) . ord)) k t)

现在,我们有“<代码”类的功能。 Char -> Char -> Int , 我们希望代之以“之类功能。 Int -> Char, 产生类功能 Char -> Char -> Char 。 我们能够利用(非常奇怪的)规则做到这一点。

f (g a b) ==> ((f .) . g) a b

这让我们:

(k t -> (((chr . (a +) . flip mod 26 . flip (-) (2*a)) .) . ((. ord) . ((+) . ord))) k t)

现在,我们只能适用减少优惠:

((chr . (a +) . flip mod 26) .) . (flip flip (2*a) . ((-) . ) . ((. ord) . (+) .ord))

我假定,你的开点是使《守则》更加简明易懂。 因此,我认为,在简化问题上也做一些其他的改动是明智之举,这样可以更容易地消除这些变量。

(k t -> chr $ a + flip mod 26 (ord k + ord t - 2*a))

首先,<代码>flip没有必要:

(k t -> chr $ a + (ord k + ord t - 2*a) `mod` 26)

其次,我将使用姓名和顺序来考虑独立可使用的功能:

encode_characters k t = chr $ encode (ord k) (ord t)
encode x y = (x + y - 2*a) `mod` 26 + a

我也给第一名发言者以一个名字,使之更加明确和可以重新使用。 encode_characters is now accessible to make pointfree using the Techno from @Nefrubyr:

encode_characters = chr . encode `on` ord

至于第二句话,我不能产生一种比其他答复所示更加可读的形式,而且其可读性低于点智形式。 因此,我建议此时不再重温,并钦佩由此产生的法典的清洁和可再使用性。

~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ ~~~~~ ~~~~~~ ~~~~~ ~~~~ ~~~~ ~~~~~~~~ ~~~~~~ ~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

PS:作为一种做法,视问题背景,对职能接口进行一些细微的改动(将数据形式纳入职能中),可能会使问题更加简单化。

A. 执行和简化职能encode_n_characters [Char] -> Char where encode_characters k t = encode_n_characters [k, t]. 其结果是否比专门性的两点职能简单?

B. 通过<代码>encode (x + y) = encode x y 和relement encode_characters 加以定义。 这两项职能是否变得更加简单? 执行是否更为简单? encode>encode, 或多或少可再使用encode?

Link on IRC, #haskell , and 问:lambdabot!:

<you> @pl (k t -> chr $ a + flip mod 26 (ord k + ord t -2*a))
<lambdabot> [the answer]




相关问题
Allow user to change the default web part styles

I have a web part which uses many SharePoint controls like menu, SPGrid, tool bar etc. I want the user to be able to change the style by specifying an external CSS file. Can somebody tell me how I ...

using jqgrid style for usual Table in asp.net mvc

I d prefer using Table and td instead of JqGrid but i like JqGrid styles. has anyone used jqgrid style for usual Grid of asp.net MVC(i mean Table and td) before?