2011-05-02 64 views
0

我有一个功能,需要终止在一定的条件。因此,例如说我们有以下功能:如何终止Haskell中的递归函数?

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一个被称为正常的,但只要我们得到的[INT]]输入负值,我们终止。所以我们只处理积极的价值观。那么你怎么能让func2发出一些信号来退出整个过程而不是继续?

+1

在调用'func2 x a:func x as'之前检查'(a:as)'中是否有负值? – 2011-05-02 06:42:52

+0

你的意思是说,当任何列表中的任何元素都为负数时,停止func的整个过程?如果是这样,你想要什么func返回?输入列表? – Ptival 2011-05-02 06:46:32

回答

0

我真的不知道你的意思,但我给它一个镜头:

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

这对于终止以同样的方式一个空列表会做一个负值计算。我希望这是你想要的。

+0

func处理Ints列表,而不是整数列表。 – Ptival 2011-05-02 06:48:07

+0

是的,但我没看到downvote的原因。他用警卫写了一个负面输入的终止基本案例。在阅读完这个问题后,我认为这是答案的重要特征。 OP可以从那里调整。 – 2011-05-02 07:04:24

+0

@jon_darkstar:看到哈马尔编辑的答案,我想这更像克里所期望的。但我必须承认,这个问题有点不清楚。 – Ptival 2011-05-02 07:41:11

5

首先,你的功能可以更简单地写成

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

现在,当遇到一个负值容易改变func2停止:

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

编辑:

所以,如果我明白这个权利,你希望整个计算失败,如果遇到负值。一种方法是将结果包装在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 
+0

这就是我第一次理解的,但我认为他可能想要停止func2被应用,只要一个列表包含一个负值... – Ptival 2011-05-02 06:49:25

+0

那么我的问题源于统一的概念。在我们寻找要添加的规则的地方,当我们遇到像X - > f(x)这样的规则时,我们返回失败,因为右侧包含x。 现在我不知道你以前是否看过统一。所以生病只是对手头的问题更具体。 – Kerry 2011-05-02 08:06:45

0

如果你不介意遍历FUNC2名单两次,这可能工作:

进口Data.Maybe

FUNC ::诠释 - > [[Int]] - > [[Int]]
func a xss =来自Just的地图。带着只是。地图(FUNC2一)$ XSS

FUNC2 ::诠释 - > [INT] - >也许[INT]
FUNC2一个XS
    |任何(< 0)xs = Nothing
    |否则=只是。 map(* a)$ xs