2016-12-15 61 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