从列表中创建元组变体 - Haskell

时间:2014-02-12 01:26:41

标签: list haskell tuples

我是一名亲戚haskell新手,我正在尝试创建一个元组列表,其中包含一个名为splits的等式,它最初来自一个列表,如下所示:

splits [1..4] --> [ ([1],[2,3,4]), ([1,2],[3,4]), ([1,2,3],[4]) ]

splits "xyz" --> [ ("x","yz"), ("xy","z") ]

创建一个包含1,然后是2,然后是3个元素等的元组列表。我发现我应该使用take / drop函数,但这是我到目前为止所遇到的并且我遇到了很多类型声明错误...任何想法?

splits :: (Num a) => [a] -> [([a], [a])]

splits [] = error "shortList"

splits [x]
       | length [x] <= 1 = error "shortList"
       | otherwise = splits' [x] 1
         where splits' [x] n = [(take n [x], drop n [x])] + splits' [x] (n+1)

4 个答案:

答案 0 :(得分:2)

Haskell-y方法是使用inits中的tailsData.List函数:

inits [1,2,3,4] = [ [],        [1],     [1,2], [1,2,3], [1,2,3,4] ]
tails [1,2,3,4] = [ [1,2,3,4], [2,3,4], [3,4], [4],     [] ]

然后我们将这两个列表压缩在一起并删除第一对:

splits xs = tail $ zip (inits xs) (tails xs)

或等效地,首先删除每个组成列表的第一个元素:

          = zip (tail (inits xs)) (tail (tails xs))

答案 1 :(得分:1)

splits [] = []
splits [_] = []
splits (x:xs) = ([x], xs) : map (\(ys, zs) -> (x:ys, zs)) (splits xs)

答案 2 :(得分:1)

你有几个错误。

Num a您无需a课程。

使用[][x]作为模式,而不是变量,请改用xs

使用++代替+来连接列表。

在我们的案例中,使用(:)将列表添加到值而不是++

为递归添加停止,例如向maxn

添加其他变量splits'
splits :: [a] -> [([a], [a])]
splits [] = error "shortList"
splits xs
       | lxs <= 1 = error "shortList"
       | otherwise = splits' xs 1 lxs
         where
           lxs = length xs
           splits' xs n maxn 
               | n > maxn  = []
               | otherwise = (take n xs, drop n xs) : splits' xs (n+1) maxn

答案 3 :(得分:0)

有一种内置功能可以满足您的需求:

splitAt :: Int -> [a] -> ([a], [a])

执行它看起来会做的事情:

> splitAt 2 [1..4]
([1,2],[3,4])

使用此功能,您可以像这样定义分割:

splits xs = map (flip splitAt xs) [1..length xs - 1]