2014-10-21 43 views
1

以下功能只能使用map和/或filter。没有fold/foldr等功能应该有以下签名和类型:apply::n f x它应该适用于f只有n times。更正式地描述一下,它看起来像这样:apply n f x = f (f...(f x)...),其中f被应用n次。映射和/或过滤器仅返回单个元素而不是列表。 HASKELL

这对地图来说非常容易实现,但问题是地图会带来并返回一个列表。我希望它只取一个整数,通过f转换它,然后返回该新整数。

我至今写了这个:(采取并返回一个列表作品)

apply::Int->(Int->Int)->[Int]->[Int] 
apply n f x 
| n==1   =map f x 
| n>1   =apply (n-1) f (map f x) 
| otherwise =x 

这是怎么了,我叫它:

main = do 
print(apply 2 (*2) [3]) 

我怎么能修改此功能,第一它不再需要并返回一个列表,而是取一个整数并返回新的修改整数?谢谢

+0

1.摆脱地图的;这将使类型'Int'; 2.考虑在你调用'apply'的行上,你只能确保'apply'被称为'n'次 - 'f'根本不被调用。但是,如果'apply(n-1)...'返回应用'f'' n-1'次的结果,你怎么能在'n'中应用'n'次呢? – 2014-10-21 22:41:48

+1

你说你只能使用'map' /'filter',但不是你必须使用。为什么不写'apply n f x | n == 1 = f x | n> 1 = apply(n-1)f(f x)|否则= x'? – genisage 2014-10-21 22:42:46

回答

4

对此,您不需要mapfilter。如果您输入列表monad的领域,则无法逃脱(如果只能使用filtermap)。这里是一个非常简单的实现,你可以在学习:

apply :: Int -> (a -> a) -> a -> a 
apply 0 _ = id 
apply 1 f = f 
apply n f = (apply (n - 1) f) . f 

Live demo

0
apply 0 _ x =      x 
apply 1 f x =      f x 
apply 2 f x = apply 1 (fmap f f)  x 
apply 3 f x = apply 1 (fmap f f) $ f x 
apply 4 f x = apply 2 (fmap f f)  x 
apply 5 f x = apply 2 (fmap f f) $ f x 

看看你是否可以概括。

PRO提示:

  1. FORALL F。 x = apply 0 (fmap f f) xf x = apply 0 (fmap f f) $ f x
  2. 如果f . g是公类型的,然后fmap f g = f . g

不知道为什么你需要地图/过滤器;也许换个问题呢?