Вот простой и лаконичный способ, хотя, вероятно, не самый эффективный:
import Data.List (find, inits)
lpref :: Int -> [Int] -> Maybe [Int]
lpref w = find (\xs -> sum xs >= w) . inits
Что касается вашей попытки, первое, что следует отметить, это то, что в обычных списках foldl
всегда неверно. Вы всегда должны использовать вместо него foldl'
или foldr
. Кроме того, тестирование null
, а затем использование head
и tail
в качестве анти-шаблона.
Вот что я бы сделал, чтобы максимизировать эффективность:
lpref :: Int -> [Int] -> Maybe [Int]
lpref w xs
| 0 >= w = Just []
| otherwise = foldr go mempty xs 0 id
where
go :: Int -> (Int -> ([Int] -> [Int]) -> Maybe [Int]) -> Int -> ([Int] -> [Int]) -> Maybe [Int]
go x acc s f
| s' >= w = Just $ f [x]
| otherwise = acc s' (f . (x:))
where s' = x + s
Это тоже максимально ленивый. lpref 6 (1:2:3:undefined)
возвращает Just [1,2,3]
.