Как завершить рекурсивную функцию в Haskell? - PullRequest
0 голосов
/ 02 мая 2011

У меня есть функция, которая должна завершаться при определенных условиях.Например, скажем, у нас есть следующие функции:

func :: Int -> [[Int]] -> [[Int]]

func _ [] = []

func x (a:as) = func2 x a:func x as

func2 :: Int -> [Int] -> [Int]

func2 _ [] = []

func2 x (a:as) = x*a:func2 x as

Допустим, я хочу, чтобы func one вызывался как обычно, но всякий раз, когда мы получаем отрицательное значение в [[Int]] ввод, мы прекращаем.поэтому мы имеем дело только с положительными ценностями.Итак, как вы могли бы заставить func2 посылать некоторый сигнал, чтобы завершить весь процесс, а не продолжать?

Ответы [ 3 ]

5 голосов
/ 02 мая 2011

Прежде всего, ваши функции могут быть написаны более просто как

func1 x = map (func2 x)
func2 x = map (*x)

Теперь легко изменить func2, чтобы остановить, когда встречается отрицательное значение:

func2 x = map (*x) . takeWhile (> 0)

EDIT:

Так что, если я правильно понимаю, вы хотите, чтобы все вычисления потерпели неудачу, если встречается отрицательное значение. Один из способов сделать это - обернуть результат в Maybe. Затем мы можем написать это в монадическом стиле:

func1 :: Int -> [[Int]] -> Maybe [[Int]]
func1 x = mapM (func2 x)

func2 :: Int -> [Int] -> Maybe [Int]
func2 x as = do
    guard $ all (>= 0) as
    return $ map (*x) as 
1 голос
/ 02 мая 2011

Я не совсем уверен, что вы имеете в виду, но я попробую:

func _ [] = []
func x (a:as) | a < 0 = []
              | otherwise = func2 x a:func x as

Это завершает вычисление для отрицательного значения так же, как пустой список. Я надеюсь, что это то, что вы хотите.

0 голосов
/ 04 мая 2011

Если вы не возражаете обходить списки в func2 дважды, это может сработать:

import Data.Maybe

func :: Int -> [[Int]] -> [[Int]]
func a xss = map fromJust.возьми пока просто.map (func2 a) $ xss

func2 :: Int -> [Int] -> Maybe [Int]
func2 a xs
|любой (<0) xs = ничего <br>|иначе = просто.карта (* a) $ xs

...