有没有办法在不创建嵌套列表的情况下使用chunksOf?

时间:2017-09-20 16:05:09

标签: haskell

我正在尝试使用chunksOf函数将函数一次映射到当前列表中的两个项目,例如。

newMerk <- map (\[x, y] -> createNode x y) . chuncksOf 2 $ mrk

并且假设我们有一个列表[x,y,z,d,f,g,h,s,t,q]我想这样做,所以看起来像这样。 [xy,zd,fg,hs,tq]代替[[xy],[zd],[fg],[hs],[tq]]

2 个答案:

答案 0 :(得分:2)

由于chunksOf能够生成动态大小的块(即,块的大小取决于仅在运行时已知的Int参数),因此它必须返回一个列表。常规元组无法工作,因为Haskell中的元组具有固定的静态长度。

对于此特定问题,您可以使用配对功能代替chunksOf

pair :: [a] -> [(a, a)]
pair = liftM2 zip odds evens

其中oddsevens分别选择奇数和偶数序数元素。那你的例子就是

newMerk <- map (uncurry createNode) (pair mrk)

对于额外的 Fun ™,您可以尝试按以下方式编写函数:

{-# LANGUAGE DataKinds, TypeFamiles #-}

import Data.Proxy
import GHC.TypeLits

type family Tuple (n :: Nat) a where
    Tuple 1 a = a
    Tuple 2 a = (a, a)
    Tuple 3 a = (a, a, a)
    Tuple 4 a = (a, a, a, a)
    ...

chunksOf :: KnownNat n => Proxy n -> [a] -> [Tuple n a]
chunksOf p xs = ???

但这似乎比它的价值更麻烦。我甚至不确定如何使用当前GHC中可用的依赖类型工具来实现这样的函数,我期望编写一个消耗[Tuple n a]的函数也会很头疼。

答案 1 :(得分:0)

使用元组代替。

newMerk <- map (\[x, y] -> createNode x y) . chuncksOf 2 $ mrk

是一个坏主意,因为[x,y]可能无法匹配。如果chunksOf具有奇数个元素,mrk最终将使用一个元素返回列表。因此,您应该尝试将mrk替换为元组列表。

  

[x,y,z,d,f,g,h,s,t,q]我想这样做,所以看起来像这样。 [xy,zd,fg,hs,tq]代替[[xy],[zd],[fg],[hs],[tq]]

这一般没有意义。如果你可以连接列表的元素,你可以使用fmap mconcat,但我认为这不是这种情况。相反,默认情况下构造列表以包含元组。