首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哈斯克尔PointFree

哈斯克尔PointFree
EN

Stack Overflow用户
提问于 2016-12-15 14:05:38
回答 2查看 222关注 0票数 1

如何将接受l(元素列表)、n ( step )并返回selected元素列表的函数测试‘转换为PointFree函数?

代码语言:javascript
复制
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)

Method2

代码语言:javascript
复制
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“P.S不能使用任何进口

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-15 14:55:11

这里有一个免费版本

代码语言:javascript
复制
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 (.))的唯一原因是为了更容易地了解文档。同样的定义是:

代码语言:javascript
复制
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),从而生成一个无导入定义:

代码语言:javascript
复制
skips = (concatMap (maybe [] return) .) . zipWith ($) . cycle . (Just:) . (`replicate` const Nothing) . pred

可以简化为

代码语言:javascript
复制
skips = (concat.) . zipWith ($) . cycle . (return:) . (`replicate` const []) . pred
票数 3
EN

Stack Overflow用户

发布于 2016-12-15 14:40:07

您可以生成一个索引列表,然后将(l !!)映射到该列表上。

代码语言:javascript
复制
mySlice l n = map (l !!) l [0,n..length l - 1]

这将比任何无点版本更容易理解。(例如,上面的内容由http://pointfree.io处理为

代码语言:javascript
复制
liftM2 (.) (map =<< (!!)) (flip (enumFromThenTo 0) . subtract 1 . length))

更新:

正如@rampion所指出的,使用带有常规列表的!!将导致性能低下,因为它不是O(1)操作。相反,尝试这个列表理解,它用一个潜在的索引列表压缩列表。

代码语言:javascript
复制
mySlice l n = [ x | (x,i) <- zip l (cycle [0..n-1]), i == 0]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41166137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档