haskell - 将值渲染到 Haskell 中的项目和中间项目中
问题描述
在进行用户界面编程时,我经常遇到需要渲染一个值列表并在渲染的值之间添加一些相关信息。在下面的代码示例中,我将数值呈现为出现在括号中的字符串,并将两个值的距离呈现为放置在值呈现之间的字符串。该代码有效,但我想知道该mystery
函数的实现是否可作为 Haskell 标准库的一部分。我也对其他库中用于此函数的名称感兴趣,因为使用人类可读的单词可以更轻松地进行谷歌搜索。
mystery :: (a -> b) -> (a -> a -> b) -> [a] -> [b]
mystery n d [] = []
mystery n d [x] = [n x]
mystery n d (x:xs) = (n x) : (d x (head xs)) : mystery n d xs
node x = "(" ++ show x ++ ")"
distance x y = "-" ++ (show $ abs $ x - y) ++ "-"
render xs = concat $ mystery node distance xs
-- render [25, 68, 54, 15] == "(25)-43-(68)-14-(54)-39-(15)"
解决方案
你的mystery
函数实际上是同时做几件事,如果你把这些行为分开,可能会更容易看到发生了什么。
首先,您正在映射n
所有元素。我们可以把它写成fmap n xs
。接下来,您正在d x y
为所有成对的相邻元素x
和y
. 我们可以把它写成zipWith d xs (tail xs)
。
最后一步是采用这两种结构并制作一个新列表,其中包含在它们之间来回交替的元素。有趣的是,这是一个9 年前提出的问题,但仍然没有一个超级令人满意的答案。可能最简单的答案是定义自己的函数:
alternate [] ys = ys
alternate (x:xs) ys = x : alternate ys xs
然后,我们可以定义mystery
为单线:
mystery n d x = alternate (fmap n x) (zipWith d x (tail x))
如果您真的希望它成为单线,那么我能想到的最好的方法就是使用concat
并且transpose
以一种时髦的方式:
mystery n d x = concat $ transpose $ (pure $ fmap n x) <> (pure $ zipWith d x (tail x))
基本上,我们使用 将两个组件制作成单例列表pure
,将它们与 融合在一起<>
,然后transpose
ing 这个“列表列表”以正确散布元素,并concat
生成结果。
推荐阅读
- python - 无法在python3.6中导入包
- windows - 在自定义程序的一个实例中打开多个文件
- java - 如何在没有 dex 的情况下在 Android 上加载类
- java - TextView 中的 HTML 文本并在新活动中打开链接
- c# - 使用 RemoveChild() 删除孩子
- r - R将一个因子列分成代表几个因子水平的几列
- python-3.x - 即使找到检查点,Tensorflow warm_start
- html - 防止子边框半径影响 IE 和 Edge 中的父级
- javascript - 如何在不知道密钥名称的情况下访问密钥
- javascript - 使用正则表达式的 Javascript 字符串拆分