运用多种功能于哈斯克尔相同的值自由点式(Applying multiple functions to

2019-07-30 16:03发布

我很无聊一天,想锻炼我的大脑,所以我决定做99个Haskell的问题 ,但限制自己的自由点式做他们。 这似乎是突然出现的时候,我做的事情的自由点,款式很多的一个问题是:如何申请多个功能相同的值,同时保持各自的结果作为一个独立的实体? 使用尖锐的表示法:

foobar x = [id x, reverse x]

而且我想出迄今无点符号:

foobar' = `map` [id, reverse] ($ x)

我似乎无法得到那个x掉那里结束。

Answer 1:

其他人已经发布了如何使用该做这个Reader的单子,但是这不是唯一的方法。 事实证明,你的第二个功能是相当接近。 我想你是要发布

foobar' x = (`map` [id, reverse]) ($ x)

由于x已接近一个最右边的位置,你几乎没有。 首先,改造部分($ x)到一个函数,因为这是一个有点容易的工作:

-- by the definition of a right operator section
foobar'2 x = (`map` [id, reverse]) (\y -> ($) y x)

接着除去x通过使一个新的变量进范围,并且将所述函数应用于从拉姆达体x

-- lambda abstraction I think...
foobar'2 x = (`map` [id, reverse]) $ (\z y -> ($) y z) x

改写这个应用程序作为一个功能组成,然后你就可以ETA减少:

-- by definition of '.'
foobar'3 x = (`map` [id, reverse]) . (\z y -> ($) y z) $ x

-- eta reduction
foobar'4 = (`map` [id, reverse]) . (\z y -> ($) y z)

最后,注意我们可以用函数替换拉姆达

-- by definition of `flip`
foobar'5 = (`map` [id,reverse]) . flip ($)

和你有一个免费的点对点形式。



Answer 2:

你会感兴趣的Applicative读者单子的实例:

instance Applicative (e ->)

使用它可以轻松地分发参数:

liftA2 (+) sin cos 3

这里sincos是函数,其中两个接收的值然后3.个体结果是使用合并(+) 您可以通过进一步结合该Category的实例(->)但五言的专业版本(.)id在已定义的Prelude

背景: Applicative例如(e ->)真表示SKI演算,其中(<*>)S组合子和pureK个组合子。 S被精确地用于一个参数分配到两个功能:

S f g x = f x (g x)

它需要一个功能应用(FG)和使得无论依赖于x((FX)(GX))。



Answer 3:

使用顺序 :

> let foobar' = sequence [id, reverse]
> foobar' "abcde"
["abcde","edcba"]


Answer 4:

有哪些弹出反复,并与各较高的概念和库重新实现,但其本质上是很简单的几个基本的惯用组合程序。 名称可能会有所不同,而在其他方面的一些是可实现:

fork (f,g) x = (f x, g x)              -- == (f &&& g)
prod (f,g) x = (f $ fst x, g $ snd x)  -- == (f *** g)
pmap f (x,y) = (f x, f y)              -- == (f *** f)
dup     x    = (x,x)

等。当然uncurry f (x,y) == fxy被使用了许多与这些,太。

&&&***定义在Control.Arrow ,以及firstsecond 。 然后prod (f,id) == first fprod(id,g) == second g等等,等等

所以,你的foobar

foobar = (\(a,b)->[a,b]) . fork (id,reverse)
       = (\(a,b)->[a,b]) . (id &&& reverse)
       = (\(a,b)->[a,b]) . (id *** reverse) . dup 
       = join $ curry ( (\(a,b)->[a,b]) . second reverse)

对于最后一个,您还需要导入Control.MonadControl.Monad.Instances 。 又见这个问题 。


后期编辑:此外,使用Control.Applicativeertes回答暗示,

       = (:) <*> ((:[]) . reverse)


文章来源: Applying multiple functions to the same value point-free style in Haskell