2015-11-12 56 views
1

使用库函数,定义一个函数halve :: [a]→([a],[a]) 将一个偶数长度的列表分成两半。例如:haskell的一半功能

> halve [1, 2, 3, 4, 5, 6] 
([1, 2, 3], [4, 5, 6]) 

到目前为止我有什么是

halve :: [a] -> ([a],[a]) 
halve = (\xs -> case xs of 
     [] -> ([],[]) 
     xs -> take ((length xs) `div` 2) xs) 

,它是错误的,因为XS - >取((长x)div 2)仅XS显示列表的前半部分..请帮助我继续下去,以便它显示列表的后半部分。

+1

http://hackage.haskell.org/package/base-4.8.1.0/docs/Prelude.html#v:splitAt – interjay

+0

它得到正确上半年'take',但也许你需要它的对手'drop'。 – Mephy

+0

相关:http://stackoverflow.com/questions/27090347/haskell-novice-trouble-with-splitting-a-list-in-half – Jubobs

回答

1

感谢评论一些解决方案。我解决它......这里是

first_halve :: [a] -> [a] 
first_halve = (\xs -> case xs of 
      [] -> [] 
      xs -> take ((length xs) `div` 2) xs) 

second_halve :: [a] -> [a] 
second_halve = (\xs -> case xs of 
      [] -> [] 
      xs -> drop ((length xs) `div` 2) xs) 

halve :: [a] -> ([a],[a]) 
halve = (\xs -> case xs of 
      [] -> ([],[]) 
      xs -> (first_halve xs, second_halve xs)) 
+0

使用['splitAt'](http://hackage.haskell.org/package/base-4.8.1.0/docs/Prelude.html#v:splitAt)会比分别调用'take'和'drop'更高效并计算两次列表的长度。根据您的要求,您甚至可能根本不需要计算列表的长度。 – Jubobs

+0

除了使用'splitAt'的好建议,我还建议仔细考虑你的病例陈述。明确检查'[]'寻址的关注点是什么?如果您不检查,您预测会出错吗? (然后,当然,这个好的科学后续问题是,这样做是错误的吗?) –