我是一名亲戚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)
答案 0 :(得分:2)
Haskell-y方法是使用inits
中的tails
和Data.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]