2016-12-15 48 views
1

如何转换我的功能测试'取l(元素列表),n(步骤)并返回步骤元素选定的列表到PointFree函数?Haskell PointFree

test' n l = test'' n l 0 
test'' n [] c = [] 
test'' n (x:xs) 0 = x:(test'' n xs 1) 
test'' n (x:xs) c 
    |n==c =x:(test'' n xs 1) 
    |otherwise =test'' n xs (c+1) 

方法2

test' m = map snd . filter (\(x,y) -> (mod x m) == 0) . zip [0..] 

test' 2 [1,2,3,4,5]结果[1,3,5] test' 2 "ASDFG结果 “ADG” PS 不能使用任何进口

+2

你为什么需要? Pointfree功能很有趣,但很少能成为解决您的问题的更好解决方案。此外,与Haskell可以做的相比,这个实现相当复杂。 – bheklilr

+0

只是大学的任务来实现测试的功能(我实现它的参数,但应该是PointFree – Spamua3

+1

@ Spamu3这个实现将是非常困难的免费,我会建议使用更多的功能从'前奏曲'首先工作。这将更容易使点免费 – bheklilr

回答

3

这里有一个免费的点对点版

import Control.Category (>>>) 
import Data.Maybe (catMaybes) 

skips = 
    pred >>>      -- \n -> n-1 
    (`replicate` const Nothing) >>> -- \n -> [ const Nothing, ..., const Nothing ] -- length n -1 
    (Just:) >>>      -- \n -> [ Just, const Nothing, ... const Nothing ] -- length n 
    cycle >>>      -- \n -> [ Just, const Nothing, ... const Nothing, Just, const Nothing, ... ] -- infinite length 
    zipWith ($) >>>     -- \n [ a0, a1, .., aN, aNPlus1, ... ] -> [ Just a0, Nothing, ..., Just aN, Nothing, ... ] 
    (catMaybes .)     -- \n [ a0, a1, .., aN, aNPlus1, ... ] -> [a0, aN, a2N, ...] 

正如其他人所说,这样的事情将是更容易理解 与贴题的定义。

我使用>>>(又名flip (.))的唯一原因是您可以更轻松地按照文档进行操作。一个等价的定义是:

skips = (catMaybes .) . zipWith ($) . cycle . (Just:) . (`replicate` const Nothing) . pred 

两个自由点名堂这是很好的凸显:

  • (`replicate` const Nothing)相当于(flip replicate (const Nothing))(\n -> replicate n (const Nothing))
  • (catMaybes .) . f相当于\n -> catMaybes . f n\n xs -> catMaybes (f n xs)

如果您不能导入catMaybes,您可以通过其自由点清晰度concatMap (maybe [] return) E放置它,使无进口定义:

skips = (concatMap (maybe [] return) .) . zipWith ($) . cycle . (Just:) . (`replicate` const Nothing) . pred 

可以简化为

skips = (concat.) . zipWith ($) . cycle . (return:) . (`replicate` const []) . pred 
+0

sry,但不能使用任何进口( – Spamua3

+0

Spamua3:更新。 – rampion

+0

这是神奇的)Thx,现在我将尝试理解这一点) – Spamua3

1

可以生成指数列表,然后在该列表上映射(l !!)

mySlice l n = map (l !!) l [0,n..length l - 1] 

这比任何免费版本都要容易得多。 (作为一个例子,上面是通过http://pointfree.io处理以

liftM2 (.) (map =<< (!!)) (flip (enumFromThenTo 0) . subtract 1 . length)) 

更新:

正如所指出的@rampion,使用!!具有规则列表将导致性能不佳,因为它是不是O(1)操作。相反,试试这个列表理解其拉链与潜力指数列表清单。

mySlice l n = [ x | (x,i) <- zip l (cycle [0..n-1]), i == 0] 
+0

注意'(!!)'将在线性的输入列表的长度,这将使'mySlice'二次。对大多数数据可能不重要,但值得注意。 – rampion

+0

不,好点。这实际上是一个非常可怕的简化。 – chepner